SW/C++

C++ : shared_ptr 와 weak_ptr : 개념, 차이, 활용법, 예제, 구현

얇은생각 2020. 5. 10. 07:30
반응형

C++ : shared_ptr 와 weak_ptr : 개념, 차이, 활용법, 예제, 구현

 

std::shared_ptr

강한 참조 기반입니다. 강한 참조 카운트를 늘려줍니다. 직접적으로 사용할 수 있습니다. 원시 포인터가 확실히 존재하기 때문입니다.

 

 

std::weak_ptr

약한 참조 기반입니다. 약한 참조 카운트를 늘려줍니다. 직접적으로 사용할 수 없습니다. lock을 써서 std::shared_ptr가 여전히 존재하는 지 확인해야 합니다. 

 

 

예제

#pragma once

#include <map>
#include <iostream>
#include <string>
#include <memory>
#include "MyVector2D.h"

using namespace std;

namespace samples
{
	class SimpleCache
	{
	public:
		SimpleCache() = default;
		~SimpleCache() = default;

		void Add(string key, weak_ptr<MyVector2D> ptr);
		shared_ptr<MyVector2D> Get(string key);

	private:
		map<string, weak_ptr<MyVector2D>> mMap;
	};
}

 

#include "SimpleCache.h"

namespace samples
{
	void SimpleCache::Add(string key, weak_ptr<MyVector2D> ptr)
	{
		auto it = mMap.find(key);

		if (it == mMap.end())
		{
			mMap.insert(pair<string, weak_ptr<MyVector2D>>(key, ptr));
			return;
		}
		
		mMap[key] = ptr;
	}

	shared_ptr<MyVector2D> SimpleCache::Get(string key)
	{
		auto it = mMap.find(key);

		if (it == mMap.end())
		{
			return shared_ptr<MyVector2D>();
		}

		if (it->second.expired())
		{
			mMap.erase(it);
			return shared_ptr<MyVector2D>();
		}

		return it->second.lock();
	}
}

 

#include <memory>
#include <iostream>
#include <cassert>
#include "CacheExample.h"
#include "SimpleCache.h"
#include "MyVector2D.h"

using namespace std;

namespace samples
{
	void CacheExample()
	{
		shared_ptr<MyVector2D> vector1 = make_shared<MyVector2D>(0, 1);
		shared_ptr<MyVector2D> vector2 = make_shared<MyVector2D>(2, 5);
		shared_ptr<MyVector2D> vector3 = make_shared<MyVector2D>(8, 4);
		
		SimpleCache cache;

		cache.Add("Candy", vector1);
		cache.Add("IceCream", vector2);
		cache.Add("Chocolate", vector3);

		shared_ptr<MyVector2D> cachedVector2 = cache.Get("IceCream");

		cout << "Usage of cachedVector2: " << cachedVector2.use_count() << endl;
		cout << "IceCream values: X: " << cachedVector2->GetX() << ", Y: " << cachedVector2->GetY() << endl;

		cache.Add("IceCream", vector3);

		cachedVector2 = cache.Get("IceCream");

		cout << "IceCream values: X: " << cachedVector2->GetX() << ", Y: " << cachedVector2->GetY() << endl;

		vector1 = nullptr;

		shared_ptr<MyVector2D> cachedVector1 = cache.Get("Candy");

		assert(cachedVector1 == nullptr);
	}
}

 

공유 포인터와 약한 포인터를 활용하여, 캐시를 구현한 예제입니다. 간단하지만, 평소에 우리도 모르게 활용하는 캐시가 어떻게 구현이 되어 있는지 알 수 있는 좋은 기회였습니다. 공유포인터와 약한포인터를 잘 활용하여, 문제를 해결할 수 있는 기회가 과연 올지는 아직은 잘 모르겠습니다. 만약 그 상황이 온다면, 적절하게 잘 활용하여 문제를 해결해보아야 겠습니다.

반응형