C++设计模式Singleton的侵入式和声明式
C++设计模式Singleton的侵入式和声明式
本期给出Singleton的最后玩法,Singleton的宏与模板,用于方便定义一个类为Singleton,少写几行代码。前面给出的Singleton玩法有:
Singleton的宏定义,通常是一种代码侵入的方式,即在原有类中植入宏代码。而Singleton的模板定义,是一种非代码侵入的声明式(我这样称呼的),在类外部添加声明代码即,而非改变原有的类。两者也有差异,Singleton的宏定义可以控制原有类的构造,而Singleton的声明式不能。如果看过C++设计模式Singleton初探
,就了解这意味着什么。
1. Singleton侵入式
Singleton的宏定义,与前面提到的各种姿式的Singleton相结合,会组合出各种各样的实现。下面给出两种常用的宏定义方式,局部静态变量宏
和unique_ptr宏
。
1)局部静态变量宏
#define SINGLETON_CLASS(ClassName)\
private:\
ClassName() = default;\
ClassName(const ClassName&) = delete;\
ClassName & operator = (const ClassName &) = delete;\
public:\
static ClassName& getInstance(){ \
static ClassName one;\
return one;\
}
使用样例:
#include "singleton.h"
class Singleton
{
SINGLETON_CLASS(Singleton)
public:
private:
};
2)unique_ptr宏
#define SINGLETON_DECLARE(ClassName) \
private: \
ClassName(){} \
ClassName(const ClassName&){} \
ClassName & operator = (const ClassName &){} \
static std::unique_ptr<ClassName> s_instance; \
public: \
static ClassName* getInstance(void);
#define SINGLETON_DEFINE(ClassName) \
std::unique_ptr<ClassName> ClassName::s_instance = nullptr; \
ClassName* ClassName::getInstance(void) \
{ \
if(nullptr == s_instance){ \
s_instance.reset(new ClassName()); \
} \
return s_instance.get(); \
}
使用样例Singleton::getInstance()
:
#include "singleton.h"
class Singleton
{
SINGLETON_DECLARE(Singleton)
public:
private:
};
SINGLETON_DEFINE(Singleton)
2. Singleton声明式
该方式利用了C++的模板,将原有的类的对象封装在一个Singleton的对象中,不改变原有类的内部代码。因此,需要对该类命名一个对应的Singleton名字,如Test
类对应的Singleton名字为TestSingleton
,用TestSingleton::instance()
来获取Test
的单例对象。
#define MAKE_SINGLETON(SingletonName, ClassName) \
class ClassName; \
using SingletonName = Singleton<ClassName>;
template<typename T>
class Singleton
{
public:
virtual ~Singleton() = default;
static T& instance()
{
if(nullptr == m_instance){
m_instance.reset(new T);
}
return *m_instance.get();
}
private:
Singleton(){}
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
Singleton(Singleton&&) = delete;
Singleton& operator=(Singleton&&) = delete;
static std::unique_ptr<T> m_instance;
};
template<typename T>
std::unique_ptr<T> Singleton<T>::m_instance = nullptr;
使用样例Test& test = TestSingleton::instance();
:
#include "singleton.h"
MAKE_SINGLETON(TestSingleton, Test)
class Test{
public:
private:
};
3. The end
NOTE: 前面给出的Singleton侵入式
和Singleton声明式
都是单线程场景下的应用方式,自行脑补多线程场景下的使用姿态就好。