모던 C++ 스타일 싱글턴 패턴을 템플릿으로 구현한다.
구현점
1. 멀티 스레드에 안전한, 전역적으로 딱 한번만 초기화하여 인스턴스가 유일함을 보장한다.
2. 템플리 클래스로 정의하고 GetInst()에서 구체 클래스의 생성자를 호출하므로 구체 클래스에서 싱글톤클래스를 friend로 선언해야한다.
3. unique_ptr의 삭제자 구조체를 선언하고 스마트포인터 인스턴스 생성시 이 호출가능한 구조체의 인스턴스를 넘겨준다.
- 템플릿 클래스에서 virtual 소멸자로 선언했기 때문에 구체 클래스에서 삭제할 멤버가 있다면 편하게 소멸자를 정의할 수 있다.
- 소멸자를 private로 선언해도 unique_ptr에서 private 소멸자를 찾을 수 없다는 에러를 없앨 수 있다.
#pragma once
#include <memory>
#include <mutex>
template<typename T>
class Singleton
{
public:
Singleton(const Singleton&) = delete;
Singleton(Singleton &&) = delete;
Singleton& operator=(const Singleton&) = delete;
Singleton& operator=(Singleton&&) = delete;
private:
struct Deleter
{
void operator()(T* inst)
{
delete inst;
}
};
private:
static std::unique_ptr<T, Deleter> m_pInst;
static std::once_flag m_flag;
protected:
Singleton() = default;
virtual ~Singleton() = default;
public:
static std::unique_ptr<T, Deleter>& GetInst()
{
std::call_once(m_flag, []()
{
Singleton<T>::m_pInst.reset(new T);
char name[256] = { 0 };
sprintf_s(name, "%s instantiated\n", typeid(T).name());
OutputDebugString(name);
});
return m_pInst;
}
};
template<typename T>
std::unique_ptr<T, typename Singleton<T>::Deleter>
Singleton<T>::m_pInst = std::unique_ptr<T, typename Singleton<T>::Deleter>(nullptr, typename Singleton<T>::Deleter());
template<typename T>
std::once_flag Singleton<T>::m_flag;
구체 클래스 예시
- 게임 타이머 클래스를 싱글톤으로 선언할 경우 예시
class Timer : public Singleton<Timer>
{
friend class Singleton<Timer>;
private:
Timer();
private:
bool m_bStop = false;
HWND m_hWnd = nullptr;
chrono::steady_clock::time_point m_Last;
unsigned int m_FrameCount = 0;
float m_fDuration = 0.f;
float m_fStopDuration = 0.f;
public:
bool IsStopped() const { return m_bStop; }
bool Init(HWND hWnd);
void Stop();
void Go();
void Reset();
float Mark() noexcept;
float Peek() const noexcept;
};
참고: bitboom.github.io/singleton-with-cpp11
'디자인 패턴 > GoF' 카테고리의 다른 글
[디자인 패턴] 행동 패턴 (11) 템플릿 메서드 Template Method (0) | 2021.04.09 |
---|---|
[디자인 패턴] 행동 패턴 (10) 방문자 Visitor (0) | 2021.04.07 |
[디자인 패턴] 행동 패턴 (9) 메멘토 Memento (0) | 2021.03.29 |
[디자인 패턴] 행동 패턴 (8) 반복자 Iterator (0) | 2021.03.24 |
[디자인 패턴] 행동 패턴 (7) 중재자 Mediator (0) | 2021.03.23 |