공유 포인터를 인수로 전달
공유 포인터로 래핑 된 객체를 선언하면 :
std::shared_ptr<myClass> myClassObject(new myClass());
그런 다음 메서드에 인수로 전달하고 싶었습니다.
DoSomething(myClassObject);
//the called method
void DoSomething(std::shared_ptr<myClass> arg1)
{
arg1->someField = 4;
}
위의 내용은 단순히 shared_pt의 참조 횟수를 증가시키고 모든 것이 멋지나요? 아니면 매달린 포인터를 남기나요?
그래도이 작업을해야합니까? :
DoSomething(myClassObject.Get());
void DoSomething(std::shared_ptr<myClass>* arg1)
{
(*arg1)->someField = 4;
}
나는 두 번째 방법이 (전체 스마트 포인터와 달리) 하나의 주소 만 복사해야하기 때문에 더 효율적일 수 있다고 생각하지만 첫 번째 방법은 더 읽기 쉽고 성능 제한을 초과 할 것으로 예상하지 않습니다. 나는 그것에 대해 위험한 것이 없는지 확인하고 싶습니다.
감사합니다.
함수에 공유 포인터를 전달하고 싶습니다. 저를 도와 줄 수 있습니까?
물론입니다. 도와 드릴 수 있습니다. 나는 당신이 C ++의 소유권 의미에 대해 어느 정도 이해하고 있다고 가정합니다. 사실인가요?
예, 저는 주제에 대해 상당히 편안합니다.
좋은.
좋아, 나는 shared_ptr
논쟁을 해야하는 두 가지 이유만을 생각할 수있다 .
- 함수는 객체의 소유권을 공유하려고합니다.
- 이 함수는
shared_ptr
s에서 특별히 작동하는 일부 작업을 수행합니다 .
어떤 것에 관심이 있습니까?
나는 일반적인 대답을 찾고 있으므로 실제로 두 가지 모두에 관심이 있습니다. 그래도 케이스 # 2에서 무슨 뜻인지 궁금합니다.
이러한 함수의 예로는 std::static_pointer_cast
, 사용자 정의 비교기 또는 술어가 있습니다. 예를 들어 벡터에서 고유 한 shared_ptr을 모두 찾아야하는 경우 이러한 술어가 필요합니다.
아, 함수가 실제로 스마트 포인터 자체를 조작해야 할 때.
바로 그거죠.
그럴 때는 참고로 통과해야한다고 생각합니다.
예. 포인터를 변경하지 않으면 const 참조로 전달하고 싶습니다. 소유권을 공유 할 필요가 없기 때문에 복사 할 필요가 없습니다. 그것이 다른 시나리오입니다.
알겠습니다. 다른 시나리오에 대해 이야기합시다.
소유권을 공유하는 사람? 확인. 어떻게 소유권을 공유 shared_ptr
합니까?
그것을 복사함으로써.
그런 다음 함수는 shared_ptr
, 맞습니까?
명백하게. 그래서 나는 그것을 const에 대한 참조로 전달하고 지역 변수에 복사합니까?
아니, 그것은 비관적이다. 참조로 전달되는 경우 함수는 수동으로 복사 할 수밖에 없습니다. 값으로 전달되는 경우 컴파일러는 복사와 이동 중에서 최상의 선택을 선택하고 자동으로 수행합니다. 따라서 가치를 전달하십시오.
Good point. I must remember that "Want Speed? Pass by Value." article more often.
Wait, what if the function stores the
shared_ptr
in a member variable, for example? Won't that make a redundant copy?
The function can simply move the shared_ptr
argument into its storage. Moving a shared_ptr
is cheap because it doesn't change any reference counts.
Ah, good idea.
But I'm thinking of a third scenario: what if you don't want to manipulate the
shared_ptr
, nor to share ownership?
In that case, shared_ptr
is completely irrelevant to the function. If you want to manipulate the pointee, take a pointee, and let the callers pick what ownership semantics they want.
And should I take the pointee by reference or by value?
The usual rules apply. Smart pointers don't change anything.
Pass by value if I'm going to copy, pass by reference if I want to avoid a copy.
Right.
Hmm. I think you forgot yet another scenario. What if I want to share ownership, but only depending on a certain condition?
Ah, an interesting edge case. I don't expect that to happen often. But when it happens you can either pass by value and ignore the copy if you don't need it, or pass by reference and make the copy if you need it.
I risk one redundant copy in the first option, and lose a potential move in the second. Can't I eat the cake and have it too?
If you're in a situation where that really matters, you can provide two overloads, one taking a const lvalue reference, and another taking an rvalue reference. One copies, the other moves. A perfect-forwarding function template is another option.
I think that covers all the possible scenarios. Thank you very much.
I think people are unnecessarily scared of using raw pointers as function parameters. If the function is not going to store the pointer or otherwise affect its lifetime, a raw pointer works just as well and represents the lowest common denominator. Consider for example how you would pass a unique_ptr
into a function that takes a shared_ptr
as a parameter, either by value or by const reference?
void DoSomething(myClass * p);
DoSomething(myClass_shared_ptr.get());
DoSomething(myClass_unique_ptr.get());
A raw pointer as a function parameter does not prevent you from using smart pointers in the calling code, where it really matters.
Yes, the entire idea about a shared_ptr<> is that multiple instances can hold the same raw pointer and the underlying memory will only be freed when there the last instance of shared_ptr<> is destroyed.
I would avoid a pointer to a shared_ptr<> as that defeats the purpose as you are now dealing with raw_pointers again.
Passing-by-value in your first example is safe but there is a better idiom. Pass by const reference when possible - I would say yes even when dealing with smart pointers. Your second example is not exactly broken but it's very !???
. Silly, not accomplishing anything and defeats part of the point of smart pointers, and going to leave you in a buggy world of pain when you try to dereference and modify things.
참고URL : https://stackoverflow.com/questions/10826541/passing-shared-pointers-as-arguments
'Nice programing' 카테고리의 다른 글
변수가 함수인지 확인하는 php is_function () (0) | 2020.10.04 |
---|---|
Javascript에서 선택적 인수의 기본값을 어떻게 설정합니까? (0) | 2020.10.04 |
우분투에서 PostgreSQL의 비밀번호 재설정 (0) | 2020.10.04 |
phpunit 모의 생성자 인수를 피하십시오 (0) | 2020.10.04 |
Google Maps API v3 : InfoWindow의 크기가 올바르게 조정되지 않음 (0) | 2020.10.04 |