vlambda博客
学习文章列表

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声明式都是单线程场景下的应用方式,自行脑补多线程场景下的使用姿态就好。