C++ CRTP 是个很有意思的东西,因为解释原理的文章很多,但是讲怎么用的就不是很多了。

今天就稍微写下CRTP(奇异递归模板模式)的一个有趣的用法:Singleton(单例模式)

单例有很多中写法,最常见的就是直接写(笑),不过今天就不介绍直接写的写法了,下面是用模版的方式来写,不过有别于其他的模版实现方式,采用的是CRTP:

     template<class ActualClass>
class Singleton
{
public:
static ActualClass* GetInstance()
{
if (m_p == nullptr)
m_p = new ActualClass;
return m_p;
}
static void ReleaseInstatnce()
{
if (m_p != nullptr)
delete m_p;
} protected:
Singleton() {}
~Singleton() {} private:
Singleton(Singleton const &);
Singleton& operator = (Singleton const &);
static ActualClass *m_p;
}; template<typename T>
T* Singleton<T>::m_p = nullptr; class SingletonClass : public Singleton<SingletonClass>
{
friend Singleton<SingletonClass>;
SingletonClass() {};
~SingletonClass() {};
};

然后用的时候就可以:SingletonClass *p = SingletonClass::GetInstance();

你还可以在SingletonClass 自己定义对应的数据类型,如果强迫症发作还接着可以将SingletonClass 模版化变成 typedef SingletonClass<T> SingletonDefine;的形式

上面的代码还不是线程安全的形式,如果想要线程安全的形式,那么如下:

 1     template<class ActualClass>
class Singleton
{
public:
static ActualClass* GetInstance()
{
static ActualClass ActualClassDefine;
return &ActualClassDefine;
} protected:
Singleton() {}
~Singleton() {} private:
Singleton(Singleton const &);
Singleton& operator = (Singleton const &);
}; class SingletonClass : public Singleton<SingletonClass>
{
friend Singleton<SingletonClass>;
SingletonClass() {};
~SingletonClass() {};
};

采用的是effect C++ 中作者给出的建议,这个方法在C++11以上都是用了锁保证了初始化的唯一性

其实CRTP还有一个最重要的功能就是编译期的“多态”,这个就暂时不讲了,下次和模版的traits一起说下

05-06 07:09