2018년 5월 21일 월요일

C++ 11/14 관련 내용 대충 정리, weak_ptr

최신 C++을 공부하려 책을 보긴 했었는데
내용이 기존 문법과 함께 여기저기 흩어져 있어 보기에 좀 어려워
MSDN을 참고하여 대충 정리하려함.


C++11/14/17 기능에 대한 지원(최신 C++)
https://msdn.microsoft.com/ko-kr/library/hh567368.aspx


weak_ptr

https://msdn.microsoft.com/ko-kr/library/hh279672.aspx


- 참조수를 늘리지 않고 개체에 엑세스 하고자 할 경우 사용
 : shared_ptr instance 사이에서 순환 참조가 발생할 경우 shared_ptr가 삭제되지 않는 경우 발생
- weak_ptr 자체는 참조 수 계산에 참가하지 않으므로 shared_ptr가 유지되는 경우에서만 사용 가능함
 : 개체가 삭제된 경우 bad_weak_ptr 예외가 발생된다.


예제 :

https://msdn.microsoft.com/ko-kr/library/hh279672.aspx#Anchor_0

번역으로 본문의 결과가 좀 이상한데 실제 실행해 보면 다음과 같다.

Creating Controller0
Creating Controller1
Creating Controller2
Creating Controller3
Creating Controller4
push_back to v[0]: 1
push_back to v[0]: 2
push_back to v[0]: 3
push_back to v[0]: 4
push_back to v[1]: 0
push_back to v[1]: 2
push_back to v[1]: 3
push_back to v[1]: 4
push_back to v[2]: 0
push_back to v[2]: 1
push_back to v[2]: 3
push_back to v[2]: 4
push_back to v[3]: 0
push_back to v[3]: 1
push_back to v[3]: 2
push_back to v[3]: 4
push_back to v[4]: 0
push_back to v[4]: 1
push_back to v[4]: 2
push_back to v[4]: 3
use_count = 1
Status of 1 = On
Status of 2 = On
Status of 3 = On
Status of 4 = On
use_count = 1
Status of 0 = On
Status of 2 = On
Status of 3 = On
Status of 4 = On
use_count = 1
Status of 0 = On
Status of 1 = On
Status of 3 = On
Status of 4 = On
use_count = 1
Status of 0 = On
Status of 1 = On
Status of 2 = On
Status of 4 = On
use_count = 1
Status of 0 = On
Status of 1 = On
Status of 2 = On
Status of 3 = On
Destroying Controller0
Destroying Controller1
Destroying Controller2
Destroying Controller3
Destroying Controller4

Controller class는 내부에 others weak_ptr를 가지고 있고
RunTest()에서 다른 shared_ptr들을 others에 삽입하여 참조하도록 하였음.

Controller class 내부의 others를 shared_ptr로 바꾸면
각각의 use_count는 5가 되고 순환 참조로 인해 Controller들이 삭제 되지 않는다.



Modern Effective C++에서 관련된 chapter는 다음과 같고
더 자세한 내용을 원한다면 책을 꼭 읽는 것을 추천.
단 Modern Effective C++이 처음이라면 Effective C++을 먼저 읽는 것을 추천.

Effective Modern C++: 42 Specific Ways to Improve Your Use of C++11 and C++14
http://a.co/0MIIC9k

Item 20: Use std::weak_ptr for std::shared_ptr- like pointers that can dangle.


- std::shared_ptr와 거의 유사하지만 참조 횟수에 영향을 미치지 않고
  지칭하는 객체를 잃은 상황을 확인할 수 있음.

std::shared_ptr<Widget> spw1 = wpw.lock();
auto spw2 = wpw.lock();
std::shared_ptr<Widget> spw3(wpw);

wpw이 expired 되었다면 spw1, spw2는 null이고
spw3를 만들때는 std::bad_weak_ptr exception 발생

아래는 책에서 말하는 loadWidget caching code임

std::shared_ptr<const Widget> fastLoadWidget(WidgetID id)
{
   static std::unordered_map<WidgetID, std::weak_ptr<const Widget>> cache;
   auto objPtr = cache[id].lock();
      if (!objPtr) {
         objPtr = loadWidget(id);
         cache[id] = objPtr;
      }
   return objPtr;
}

cache에 있는 widget이 만료되지 않았다면 (lock() != nullptr) cache된 widget을 제공.

- shared_ptr 개체를 참조할 때 순환 참조를 피하고자 사용하지만 이는 일반적인 상황은 아님,,,

댓글 없음:

댓글 쓰기