Programing

참조로 shared_ptr을 전달해야합니까?

lottogame 2020. 9. 1. 07:55
반응형

참조로 shared_ptr을 전달해야합니까? [복제]


이 질문에 이미 답변이 있습니다.

shared_ptr을 전달하는 모범 사례는 무엇입니까?

현재 다음과 같이 shared_ptr 함수 인수를 전달합니다.

void function1( shared_ptr<TYPE>& value );

제어 된 상황에서는 상수 참조로 공유 포인터를 전달할 수 있습니다 . 누구에게도 객체를 동시에 삭제하지 않도록해야합니다.하지만 누구에게 참조를 제공하는지주의한다면 그렇게 어렵지는 않습니다.

일반적으로 공유 포인터를 직선 사본 으로 전달해야합니다 . 이것은 의도 된 의미를 제공합니다. 공유 포인터의 복사본을 포함하는 모든 범위는 소유권의 "공유"를 통해 개체를 활성 상태로 유지합니다.

항상 가치를 전달하지 않는 유일한 이유는 공유 포인터를 복사하는 것이 원자 참조 카운트 업데이트로 인해 특정 가격이 발생하기 때문입니다. 그러나 이것은 주요 관심사가 아닐 수도 있습니다.


선택적 다이 그 레션 :

주요 질문에 대한 답변이 되었기 때문에, 아마도 당신이해야하는 몇 가지 방법을 고려하는 교훈이다 결코 공유 포인터를 사용하지합니다. 여기에 약간의 사고 실험이 있습니다. 공유 포인터 유형을 정의 해 보겠습니다 SF = std::shared_ptr<Foo>. 참조를 고려하기 위해 함수 인수를 전달하는 대신 유형을 살펴 보겠습니다 RSF = std::reference_wrapper<T>. 즉, 공유 포인터가있는 경우 SF p(std::make_shared<Foo>());를 통해 값 의미를 가진 참조 래퍼를 만들 수 있습니다 RSF w = std::ref(p);. 설정에 너무 많이.

이제 모든 사람들은 포인터 컨테이너가 지뢰밭이라는 것을 알고 있습니다. 따라서 std::vector<Foo*>유지 관리하는 데 악몽이 될 것이며 부적절한 수명 관리로 인해 많은 버그가 발생합니다. 개념적으로 더 나쁜 것은 컨테이너가 포인터를 저장하는 객체 소유사람이 누구인지 명확하지 않다는 것입니다 . 포인터는 동적 개체, 자동 개체 및 쓰레기에 대한 포인터의 혼합 일 수도 있습니다. 아무도 알 수 없습니다. 따라서 표준 솔루션은 std::vector<SF>대신 사용하는 것입니다. 이것이 공유 포인터를 사용하는 올바른 방법입니다. 반면에 절대 사용해서는 안되는 것은std::vector<RSF>-이것은 네이 키드 포인터의 원래 벡터와 실제로 매우 유사한 관리 할 수없는 괴물입니다! 예를 들어, 참조를 보유한 객체가 아직 살아 있는지 여부는 명확하지 않습니다. 공유 포인터를 참조하는 것은 전체 목적을 무너 뜨 렸습니다.

두 번째 예에서는 SF p이전과 같이 공유 포인터가 있다고 가정 합니다. 이제 int foo(SF)동시에 실행하려는 함수가 있습니다 . std::thread(foo, p)스레드 생성자가 인수 복사본만들기 때문에 일반적인 방법 은 잘 작동합니다 . 그러나 std::thread(foo, std::ref(p))우리가라고 말했 더라면 우리는 모든 종류의 문제에 처했을 것입니다. 호출 범위의 공유 포인터가 만료되어 객체를 파괴 할 수 있으며, 매달린 참조와 유효하지 않은 포인터가 남게됩니다!

나는이 두 가지 꽤 인위적인 예제가 당신이 정말로 당신의 공유 포인터가 카피 로 전달되기를 원할 때 약간의 빛을 비추 길 바랍니다 . 잘 설계된 프로그램에서는 누가 어떤 리소스를 담당하고 있는지 항상 명확해야하며 올바르게 사용할 경우 공유 포인터는 작업에 유용한 도구입니다.


그것은 당신이 원하는 것에 달려 있습니다. 수신자가 객체의 소유권을 공유해야합니까? 그런 다음 자체 shared_ptr. 따라서 값으로 전달하십시오.

함수가 단순히 호출자가 소유 한 객체에 액세스해야하는 경우 계속 진행하여 (const) 참조를 전달하여 shared_ptr.

C ++의 모범 사례는 항상 객체에 대해 명확하게 정의 된 소유권 의미를 갖는 것입니다. 실제적인 생각 을 대체 할 보편적 인 "항상 이렇게하는 것"은 없습니다 .

공유 포인터 항상 값으로 전달하면 비용이 많이 듭니다 (원시 포인터보다 복사하는 데 훨씬 비싸기 때문입니다). 당신이 경우 결코 그것을하지, 그 첫 번째 장소에서 공유 포인터를 사용 이유가 없다.

새 함수 나 개체가 pointee의 소유권을 공유해야 할 때 공유 포인터를 복사합니다.


참조로 전달하는 경우 const 참조로 전달하십시오. 그것은 당신이 성능상의 이유로 ref를 통과하고 있음을 분명히합니다. 또한 가능한 경우 make_shared를 사용하십시오. 이는 간접적 인 것을 저장하므로 성능이 향상됩니다.

참고 URL : https://stackoverflow.com/questions/8385457/should-i-pass-a-shared-ptr-by-reference

반응형