2014-03-06 2 views
1

필자가 모든 shared_ptr 객체를 사용하고 주기적 종속성이있는 경우 약 포인터가 순환 종속성 문제에 사용됩니다. 약한 포인터는 사이클을 깨는 데 사용됩니다. 약한 포인터는 공유 포인터를 생성하는 lock()을 사용하여 이것을 달성합니다.weak_pointer.lock()은 weak_ptr을 생성하는데 사용 된 원래 shared_ptr의 참조 카운트를 증가시킵니다.

class A { shared_ptr<B> b; ... }; 
class B { weak_ptr<A> a; ... }; 
shared_ptr<A> x(new A); // +1 
x->b = new B;   // +1 
x->b->a = x;   // No +1 here 

하지만 지금은 내가 전화 잠금을 만든 가정의 x> B-> a.lock(), 그래서 X의 심판이 카운트는 2가 될 것이고, x는 범위를 떠나면, 여전히 메모리 누수 바로 거기에있을 것입니다 ? lock()을 사용하여 공유 포인터를 만들었 기 때문에 ref 수는 2가되었습니다. 제 이해가 정확한지 아닌지 알려주세요.

+3

'lock()'에 의해 생성 된 객체가 소멸자에 의해 파괴 될 때, 그 객체는 카운트를 다시 감소시킨다. –

+1

'lock()'의 반환 값으로 무엇을합니까? 이를 + 시하면 즉시 잠금이 다시 제거됩니다. – aschepler

+0

공정한 [간단한 샘플 프로그램] (https://ideone.com/3JQsaX)은 어떤 일이 일어나는지 보여줍니다. 자물쇠()는 사용하는 동안 가치가 거의 없습니다. – WhozCraig

답변

3

shared_ptr 공유 객체에 대한 참여 별개의 참조 카운트가 있습니다

  • 객체에 대한 참조의 수, 즉 shared_ptr 인스턴스.
  • 제어 블록, 즉 shared_ptrweak_ptr 인스턴스에 대한 참조의 수.

weak_ptr은 후자의 카운트에만 기여합니다. 모든 shared_ptr 인스턴스가 삭제되면 개체 삭제자가 호출됩니다. 일반적으로이 개체 삭제자가 개체를 삭제하는 기본값입니다. 약한 포인터가 있으면 제어 블록이 계속 존재합니다. 또한 모든 약 포인터가 파괴되면 제어 블록이 파괴됩니다.

(각 shared_ptr 인스턴스에서 직접 캐싱 객체 포인터를 최적화하는 것을 무시하십시오.) 귀하의 경우에는 A 인스턴스에 대한 포인터가있는 제어 블록에 x이 가리키고 있습니다. 그리고 그 인스턴스의 b 멤버는 B 인스턴스에 대한 포인터를 가진 두 번째 컨트롤 블록을 가리키고 있습니다. 마지막으로 해당 인스턴스에는 x이 가리키는 제어 블록에 대한 포인터가 있는데, 이는 원형 예이지만 소유권의 원형은 아닙니다.