글 작성자: Sowhat_93

메모리풀을 만들때에

AllocInstance나 ReleaseInstance같은 정적함수들을 구현해서

객체 생성시에 사용하기도 한다.물론 좋은 방법이지만, 템플릿을 사용할때에 귀찮은 일이 발생한다.

 

템플릿 함수 내에서

풀링을 사용하려면 강제로 형변환을 해야하며,

AllocInstance 와 ReleaseInstance 사용하는 경우와

그렇지 않은 경우를 두개를 만들어야 한다.

 

귀찮은 여러 작업이 동반된다는 것은

다시말해 그만큼 타입 특정에 대해서 실수할 위험성이

항상 존재한다는 이야기이기도 하다.

 

템플릿으로 인터페이스를 만들고

new 와 delete를 오버로딩하는 방법을 사용하면, 

이런 귀찮음과 위험을 해결할 수 있다.

new와 delete는 어디까지나 연산자이기 때문이다.

 

별도로 Initialize 같은 함수를 호출하지 않아도 된다.

new 연산자를 사용하면 자동으로 생성자가 호출된다.

잘 모른다면 여기를 참고한다.

 

[프로그래밍/C++] - [C++] C++ 생성자 강제 호출 및 new 연산자

 

[C++] C++ 생성자 강제 호출 및 new 연산자

기본적으로 사용하는 new를 사용해보자. #include class MyClass { private: int Number = 9935; public: MyClass() { std::cout << "MyClass!" << std::endl; } virtual ~MyClass() {} }; int main() { MyClass*..

so-what-93.tistory.com

 

 

이를 통해 풀링을 사용하던, 아니던 생성자에 초기화 루틴을

넣게 되는 확실한 규칙을 세울 수 있어 협업시에도 아주 유용하다.  

 

 

std::list를 사용한 간단한 구현은 다음과 같다.

참고로 new 와 delete는 연산자 오버로딩시 static으로 취급된다.

 

#include <iostream>
#include <list>

//--------------------------
//Interface.
template <class T> 
class MyPoolInterFace
{
private:
	static std::list<T*> m_listPool;

public:
	static void* operator new (size_t Size)
	{
		if (m_listPool.empty())
			return malloc(sizeof(T));

		void* ret = m_listPool.front();
		m_listPool.pop_front();
		
		return ret;
	}

	static void operator delete(void* pReleaseTarget)
	{
		m_listPool.push_back((T*)pReleaseTarget);
		return;
	}
};
template <class T>
std::list<T*> MyPoolInterFace<T>::m_listPool = std::list<T*>();



//--------------------------
//Example Class.
class MyClass : public MyPoolInterFace<MyClass>
{
private:
	int Number = 9935;
public: 

	void PrintNumber()
	{
		std::cout << Number << std::endl;
	}

	MyClass() 
	{
		std::cout << "MyClass!" << std::endl;
	}
	virtual ~MyClass() {}
};




int main()
{
	MyClass* pMyInstance = new MyClass();
	pMyInstance->PrintNumber();


}