C++ CRTP singleton
C++ CRTP 是个很有意思的东西,因为解释原理的文章很多,但是讲怎么用的就不是很多了。
今天就稍微写下CRTP(奇异递归模板模式)的一个有趣的用法:Singleton(单例模式)
单例有很多中写法,最常见的就是直接写(笑),不过今天就不介绍直接写的写法了,下面是用模版的方式来写,不过有别于其他的模版实现方式,采用的是CRTP:
1 template<class ActualClass> 2 class Singleton 3 { 4 public: 5 static ActualClass* GetInstance() 6 { 7 if (m_p == nullptr) 8 m_p = new ActualClass; 9 return m_p; 10 } 11 static void ReleaseInstatnce() 12 { 13 if (m_p != nullptr) 14 delete m_p; 15 } 16 17 protected: 18 Singleton() {} 19 ~Singleton() {} 20 21 private: 22 Singleton(Singleton const &); 23 Singleton& operator = (Singleton const &); 24 static ActualClass *m_p; 25 }; 26 27 template<typename T> 28 T* Singleton<T>::m_p = nullptr; 29 30 class SingletonClass : public Singleton<SingletonClass> 31 { 32 friend Singleton<SingletonClass>; 33 SingletonClass() {}; 34 ~SingletonClass() {}; 35 };
然后用的时候就可以:SingletonClass *p = SingletonClass::GetInstance();
你还可以在SingletonClass 自己定义对应的数据类型,如果强迫症发作还接着可以将SingletonClass 模版化变成 typedef SingletonClass<T> SingletonDefine;的形式
上面的代码还不是线程安全的形式,如果想要线程安全的形式,那么如下:
1 template<class ActualClass> 2 class Singleton 3 { 4 public: 5 static ActualClass* GetInstance() 6 { 7 static ActualClass ActualClassDefine; 8 return &ActualClassDefine; 9 } 10 11 protected: 12 Singleton() {} 13 ~Singleton() {} 14 15 private: 16 Singleton(Singleton const &); 17 Singleton& operator = (Singleton const &); 18 }; 19 20 21 class SingletonClass : public Singleton<SingletonClass> 22 { 23 friend Singleton<SingletonClass>; 24 SingletonClass() {}; 25 ~SingletonClass() {}; 26 };
采用的是effect C++ 中作者给出的建议,这个方法在C++11以上都是用了锁保证了初始化的唯一性
其实CRTP还有一个最重要的功能就是编译期的“多态”,这个就暂时不讲了,下次和模版的traits一起说下