1,本節課講述單例類模式,實現並抽取相關代碼實現單例類模板,在以后開發工作 中,如果想要使用單例模式,那么直接使用今天開發的單例類模板就可以;
2,需求的提出:
1,在架構設計時,某些類在整個系統生命期中最多只能有一個對象存在 ( Single Instance );
1,如超市收銀系統,由外觀來說其由顯示器、掃描槍、收款箱組成,這幾部分都只有一個部件,用面向對象的思想來進行架構設計的話,掃描槍應該對應到代碼里面的一個類,它應該用來創建對象,實際的硬件只有一個掃描槍,肯定要限制掃描槍對應的類只能創建一個對象;
2,這個時候單例模式的需求就出來了;
3,問題:
1,如何定義一個類,使得這個類最多只能創建一個對象?
4,單例模式:
1,要控制類的對象數目,必須對外隱藏構造函數;
1,要創建一個對象,必然要調用構造函數,因此可以控制構造函數的訪問屬性;
2,思路:
1,將構造函數的訪問屬性設置為 private;
1,外界就不能創建對象了;
2,定義 instance 並初始化為 NULL;
3,當需要使用對象時,訪問 instance 的值;
1,空值:創建對象,並用 instance 標記;
2,非空值:返回 instance 標記的對象;
5,單例模式初探編程實驗:
#include <iostream> #include <string> using namespace std; class SObject { static SObject* c_instance; // 定義標識符指針; /* 不需用拷貝和賦值 */ SObject(const SObject&); SObject& operator= (const SObject&); SObject() // 構造函數創建為私有的; { } public: static SObject* GetInstance(); void print() { cout << "this = " << this << endl; } }; SObject* SObject::c_instance = NULL; //類的外部對靜態變量定義並初始化; SObject* SObject::GetInstance() // 創建對象 { if( c_instance == NULL ) { c_instance = new SObject(); } return c_instance; } int main() { SObject* s = SObject::GetInstance(); SObject* s1 = SObject::GetInstance(); SObject* s2 = SObject::GetInstance(); s->print(); // this = 0x940a008 s1->print(); // this = 0x940a008 s2->print(); // this = 0x940a008 return 0; }
1,上述代碼中並沒有釋放這個唯一的對象,這是因為單例模式所對應的對象在系統的生命周期中都是存在的,如果這個系統還在運行,就不需用釋放它;
2,單例模式所得到的對象在整個系統運行過程中是絕對不釋放的;
6,單例模式存在問題(這里做的是錦上添花的事,要求完美):
1,需要使用單例模式時:
1,必須定義靜態成員變量 c_instance;
2,必須定義靜態成員函數 GetInstance();
2,如果現在要開發超市收銀系統,那么開發掃描槍對應的類需要用單例模式來實現,收款箱對應的類也要用單例模式來實現,這個時候就要寫重復的靜態成員變量和靜態成員函數;
3,靜態成員變量和靜態成員函數和我們類的實際功能沒有關系,這是單例模式的邏輯;
7,解決方案:
1,將單例模式相關的代碼抽取出來,開發單例類模板,當需要單例類時,直接使用單例類模板;
8,單例類模板編程實驗:
1,單例模式類模板 Singleton.h 文件:
1 #ifndef _SINGLETON_H_ 2 #define _SINGLETON_H_ 3 4 template 5 < typename T > 6 class Singleton 7 { 8 static T* c_instance; 9 public: 10 static T* GetInstance(); 11 }; 12 13 template 14 < typename T > 15 T* Singleton<T>::c_instance = NULL; 16 17 template 18 < typename T > 19 T* Singleton<T>::GetInstance() 20 { 21 if( c_instance == NULL ) 22 { 23 c_instance = new T(); 24 } 25 26 return c_instance; 27 } 28 29 #endif
2,單例模式的使用:
1 #include <iostream> 2 #include <string> 3 #include "Singleton.h" 4 5 using namespace std; 6 7 class SObject 8 { 9 friend class Singleton<SObject>; // 當前類需要使用單例模式 10 11 SObject(const SObject&); 12 SObject& operator= (const SObject&); 13 14 SObject() 15 { 16 } 17 public: 18 19 void print() 20 { 21 cout << "this = " << this << endl; 22 } 23 }; 24 25 int main() 26 { 27 SObject* s = Singleton<SObject>::GetInstance(); 28 SObject* s1 = Singleton<SObject>::GetInstance(); 29 SObject* s2 = Singleton<SObject>::GetInstance(); 30 31 s->print(); // 0x9621008; 32 s1->print(); // 0x9621008; 33 s2->print(); // 0x9621008; 34 35 return 0; 36 }
3,使用單例類模板方法:
1,構建對象的函數全部私有化;
2,聲明單例類模板為此類的友元(可以訪問這個類);
4,此單例類模板在我們今后開發工作中都可以使用;
9,小結:
1,單例模式是開發中最常用的設計模式之一;
2,單例模式的應用使得一個類最多只有一個對象;
3,可以將單例模式相關的代碼抽象成類模板;
4,需要使用單例模式的類直接使用單例類模板;