C++11 적용: 개체 풀

4425 단어
자세히 보기
    ObjectPool.hpp:
#pragma once

#include 
#include 
#include 
#include 

using namespace std;

template 
class ObjectPool
{
	template 
	using Constructor = std::function<:shared_ptr>(Args...)>;
public:
	~ObjectPool()
	{
		destructedFlag = true;
	}

	//  
	template 
	void Init(size_t num, Args&&... args)
	{
		if (num <= 0)
		{
			throw std::logic_error("object num out of range!");
		}
		m_object_map.clear();
		auto constructName = typeid(Constructor).name(); //  
		for (size_t i = 0; i < num; i++)
		{
			m_object_map.emplace(constructName, std::shared_ptr(new T(std::forward(args)...), [this, constructName](T* p)
			{
				// ( ) , , 
				if (!destructedFlag) //  , ObjectPool ,T , emplace 
				{
					m_object_map.emplace(std::move(constructName), std::shared_ptr(p));
				}
				else {
					delete p;
				}
			}));
		}
	}
	//  
	template 
	std::shared_ptr Get()
	{
		string constructName = typeid(Constructor).name();
		auto range = m_object_map.equal_range(constructName);
		for (auto it = range.first; it != range.second; ++it)
		{
			auto ptr = it->second;
			m_object_map.erase(it);
			return ptr;
		}
		return nullptr;
	}

private:
	multimap> m_object_map;
	bool destructedFlag = false;

};

테스트 코드:
#include 
#include   

#include "ObjectPool.hpp"
 
using namespace std;

struct MyObj
{
	MyObj() 
	{
		cout << "MyObj construct... 0x" << hex << this << endl;
	}
	MyObj(int a)
	{
		cout << "MyObj construct:" << a << " 0x" << hex << this << endl;
	}
	MyObj(const int& a, const int& b) 
	{
		cout << "MyObj construct a:" << a << " b:" << b << " 0x" << hex << this << endl;
	}
	~MyObj()
	{
		cout << "MyObj destruct... 0x" << hex << this << endl;
	}
	void print(const string& str)
	{
		cout << "print:" << str.c_str() << endl;
	}
};
void printTest(std::shared_ptr p, const string& str)
{
	if (p != nullptr)
	{
		p->print(str);
	}
	else {
		cout << "printTest error: p is nullptr..." << endl;
	}
}

void TestObjPool() 
{
	ObjectPool pool;
	pool.Init(2); //  

	//  , 
	{
		auto p1 = pool.Get();
		printTest(p1, "p1...");

		auto p2 = pool.Get();
		printTest(p2, "p2...");
		cout << "---------------------" << endl;
	}

	auto p1 = pool.Get();
	auto p2 = pool.Get();
	printTest(p1, "p1");
	printTest(p2, "p2");
	cout << "===========================0" << endl;

	ObjectPool pool2;
	pool2.Init(2, 1); //  , 1 
	auto p4 = pool2.Get();
	printTest(p4, "p4");
	cout << "===========================1" << endl;

	pool.Init(2, 3, 4); //  , 3 4 
	auto p5 = pool.Get();
	printTest(p5, "p5");
	cout << "===========================2" << endl;
}

int main(int, char *[])
{     
	
	TestObjPool(); 

	system("pause");
	return 0;
}

같은 ObjectPool에서 Init를 여러 번 실행할 수 있지만, 모든 Init가 만든 실례는 이 ObjectPool이 실행될 때 실행될 수 있습니다. 
 
 

좋은 웹페이지 즐겨찾기