weak_ptr

#include <iostream>
#include <memory>
#include <list>
#include <algorithm>

using namespace std;

struct Foo
{
	Foo(int number)
		: number(number)
	{ cout << "ctor(" << number << ")"<< endl; }
	~Foo()
	{ cout << "dtor(" << number << ")"<< endl; }

	int number;
};

void main()
{
	list<shared_ptr<Foo>> originallist;;
	list<weak_ptr<Foo>> list;

	//원본이 존재하지 않는 weak_ptr은 dangle이므로 원본을 유지하는 리스트를 작성.
	for (int i = 0; i < 10; i++)
		originallist.push_back( make_shared<Foo>(i) );

	for (auto& itr : originallist)
		list.push_back( itr );

	weak_ptr<Foo> temp;
	const int someIndex = 6;

	for (auto itr : list)
	{
		//이 루프 내에서만 shaerd_ptr로 사용.
		//방어적 코딩을 할 때는 lock의 결과가 nullptr이 아닌 것을 확인한 후에 사용해야 안전하다.
		auto item (itr.lock());
		cout << item->number << endl;

		if (item->number == someIndex)
			temp = itr;
	}

	//weak_ptr은 operator== 을 구현하지 않는다. 따라서 find를 사용할 수 없음
	//find가 필요할 경우 find_if와 shared_ptr을 비교하는 람다를 사용해야 한다.
	//D라면 lambda에서도 타입 추론이 되니까 auto 넣으면 끝인데
	//C++은 lambda안에서는 auto 사용 불가능이라 유감.
	auto selector = [&temp](weak_ptr<Foo> item){ return item.lock() == temp.lock();};

	auto itr (std::find_if(list.begin(), list.end(), selector));

	auto foundItem (itr->lock());

	cout << "found item : " << foundItem->number << endl;
}

todo: raw pointer와 weak_ptr을 컨테이너와 함께 사용할 때의 오버헤드를 벤치마크 해보거나 자료를 찾아볼 필요가 있겠다. weak_ptr은 컨테이너에 넣어서 사용하기에는 너무 불편한 점이 많다. 컨테이너와 사용할 경우에는 shared_ptr을 사용하거나, 순환참조가 있을 경우에는 raw pointer를 사용하는 것이 나을 듯.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.