C++设计模式--单例模式(Singleton)及单例通用模板
概述
C++中的單例模式應該是設計模式中最簡單的了,在編碼中常見到。那么,簡單的總結下 C++中的單例模式寫法,以及根據單例模式擴展后的一些寫法,最后還有單例的通用模板,可用于快捷創建一個單例類。
單例類
創建一個單例模式的關鍵是防止他人獲得任何控制其對象生存期的權利,也就是說不要讓別人可以隨便創建類對象,單例類在整個程序生存周期中至始至終就只有一個對象,為了做到這一點,必須要先把構造函數聲明為私有,并且防止編譯器隱式生成任何構造函數。
注意:拷貝構造函數和賦值操作符無需實現,因為根本就不會在單例中被調用
然后為了只實現只保留一個對象,需要將對象通過靜態創建來實現,并且可以在調用的時候再進行創建,這種方式叫惰性初始化。
接下來看一下單例的通用寫法:
#include <iostream>using namespace std;class Singleton { public:static Singleton & instance(){return s;}int getValue(){return i;}void setValue(int x){i = x;}private:static Singleton s;int i;Singleton(int x):i(x){} };Singleton Singleton::s(47);int main() {Singleton & s = Singleton::instance();cout<< s.getValue() << endl;Singleton &s2 = Singleton::instance();s2.setValue(4);cout<< s.getValue() << endl;return 0; }輸出結果:
47 4代碼很簡單,調用靜態函數 instance()返回的是引用而不是指針,如果是指針的話用戶可能會不小心刪除此指針,因此上面這種寫法被認為是最安全的。
當然,這種方法并沒有限制只創建一個對象,也可以通過這種方式創建有限個對象的對象池,但是這種情況下可能遇到池中共享對象的問題,需要創建一個對共享對象進出對象池登記的方法啦解決。不過通常我們寫單例類都只創建一個對象, 那么就不用考慮啦。
以上程序還可以做得更加簡單,我們可以將在一個成員函數內部的靜態對象的創建與單例類結合在一起,如下:
#include <iostream>using namespace std;class Singleton { public:static Singleton & instance(){ // return s;static Singleton s(47);return s;}int getValue(){return i;}void setValue(int x){i = x;}private:static Singleton s;int i;Singleton(int x):i(x){}Singleton & operator =(Singleton&); //賦值操作符 不會調用Singleton(const Singleton&);//拷貝構造函數 不會調用 };//Singleton Singleton::s(47);int main() {Singleton & s = Singleton::instance();cout<< s.getValue() << endl;Singleton &s2 = Singleton::instance();s2.setValue(4);cout<< s.getValue() << endl;return 0; }只對第一個程序做了簡單的修改,可以看到,在調用instance函數的時候才去創建靜態對象。這種寫法更簡單一些。
單例類通用模板
根據單例類的特征,我們可以寫一個通用模板,如下:
#include <iostream>using namespace std;template<class T> class Singleton { public:static T& instance(){static T theInstance;return theInstance;}protected:Singleton(){}virtual ~Singleton(){}private: // Singleton(const Singleton&); // Singleton& operator =(const Singleton&);};//單例類 class MyClass : public Singleton<MyClass> { public:void setValue(int n){x = n;}int getValue(){return x;}protected:friend class Singleton<MyClass>;MyClass(){x = 0;}private:~MyClass();int x; };int main() {MyClass& m = MyClass::instance();cout << m.getValue() << endl;m.setValue(1);cout << m.getValue() << endl;return 0; }以上可以看到,MyClass 類可以通過繼承模板來快速實現一個單例模式。通過下面三個步驟來實現:
- 1.聲明其構造函數為私有或保護
- 2.聲明類Singleton為友元
- 3.從Singleton派生出 MyClass
第三點可能不太容易理解,這里只是對模板 Singleton 中模板參數的靜態依賴。換句話說,類 Singleton的代碼之所以能夠被編譯器實例化,是因為它不依賴于類 MyClass 的大小,當函數Singleton::instance()第一次被調用時,才需要類 MyClass 的大小,而此時編譯器已經知道類 MyClass 的大小。
參考資料:《C++編程思想》
總結
以上是生活随笔為你收集整理的C++设计模式--单例模式(Singleton)及单例通用模板的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++设计模式--代理模式(Proxy)
- 下一篇: C++设计模式--状态模式(state)