[boost] weak_ptr

출처 : http://sweeper.egloos.com/3059940

1. shared_ptr
shared_ptr의 내용은 다음 링크를 참고하기 바라며, 특히 3-9 Circular reference 챕터를 자세히 읽어보기 바란다.
(위 링크엔 shared_ptr의 circular reference에 대한 예제가 포함되어 있다)
2. weak_ptr
shared_ptr은 자신이 참조하고 있는 객체(메모리 주소)에 대해 reference counting을 함으로써, 객체의 수명에 직접적으로 관여한다.
shared_ptr 객체 하나가 소멸되더라도, 동일한 메모리 주소를 참조하고 있는 다른 shared_ptr 객체가 있으면 참조하고 있던 메모리 주소의 객체는 소멸되지 않는다.
하지만, weak_ptr은 shared_ptr을 관리하기 위한 reference count에 포함되지 않는다.
즉, shared_ptr의 객체만 참조할 뿐, shared_ptr의 reference count를 올리지 않는 것이다.
사실 weak_ptr이 shared_ptr을 참조할 때 shared_ptr의 weak reference count는 증가시킨다.
객체의 생명 주기에 관여하는 strong reference count를 올리지 않는 것 뿐이다.
(shared_ptr, weak_ptr 객체를 디버거로 살펴보면 strong/weak refCount가 따로 표시된다)
(weak reference count는 객체의 소멸에는 전혀 관여하지 않으니 헤깔리지 말도록!)
위에서 얘기한 것처럼, weak_ptr은 shared_ptr의 참조자라고 표현하는 것이 맞을 듯 하다.
같은 weak_ptr 또는 shared_ptr로부터만 복사 생성/대입 연산이 가능하며,
shared_ptr로만 convert가 가능하다.
따라서, weak_ptr<_Ty>는 _Ty 포인터에 대해 직접 access가 불가능하며,
(shared_ptr의 get() 메쏘드 같은 녀석이 아예 없다)
_Ty 포인터에 엑세스를 원하면 lock 메써드를 통해 shared_ptr로 convert 한 뒤, shared_ptr의 get 메쏘드를 사용해야 한다.

그리고  expired 함수를 통해 자신이 참조하고 있는 shared_ptr의 상태(즉, weak_ptr의 상태)를 체크할 수 있다.

 
3. 예제
지금까지의 내용에 대한 이해를 돕기 위해 wikipedia에서 소개하는 예제부터 살펴보자.
4. Circular reference 회피 예제
shared_ptr 문서의 circular reference 예제를 weak_ptr을 사용해 개선시켜 보았다.
아래 예제와 비교해 보길 바란다.
4. weak_ptr 정리
weak_ptr은 다음과 같은 경우에 사용하면 유용하다.
  • 어떠한 객체를 참조하되, 객체의 수명에 영향을 주고 싶지 않은 경우
  • 그리고 매번 특정 객체의 ID로 컬렉션에서 검색하고 싶지 않을 경우
  • 그러면서 dangling pointer의 잠재 위험성을 없애고 싶을 때

답글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.