1.功能: 只能有一個實例的類,用於類似計數、記憶體池的情況。 2.實現方法: [1]構造函數設置為private,因此不能在外部創建實例。 [2]提供一個public方法訪問實例。 [3]析構函數,析構函數是為了銷毀這個類的成員變數,private和public都可以,但是析構函數裡面不能delet ...
1.功能:
只能有一個實例的類,用於類似計數、記憶體池的情況。
2.實現方法:
[1]構造函數設置為private,因此不能在外部創建實例。
[2]提供一個public方法訪問實例。
[3]析構函數,析構函數是為了銷毀這個類的成員變數,private和public都可以,但是析構函數裡面不能delete這個類的實例(析構函數裡面delete實例本身就是有問題的,因為delete會調用析構函數,析構裡面又delete,會造成遞歸)。
[4]實例銷毀方法:一種是定義一個垃圾回收類,自動銷毀這個實例;一種是在外面手動delete這個實例;還一種是定義為訪問函數裡面的靜態成員,當程式退出的時候自動釋放這個實例。
3.代碼實現:
[1]函數內部靜態成員變數方式,第一次訪問的時候創建實例,並且線程安全:
1 #include <iostream> 2 #include <stdio.h> 3 using namespace std; 4 5 class singleton 6 { 7 public: 8 static singleton *get_instance(){ 9 static singleton single; 10 return &single; 11 } 12 private: 13 singleton(){ 14 printf("singleton() called.\n"); 15 } 16 17 ~singleton(){ 18 printf("~singleton() called.\n"); 19 } 20 }; 21 22 23 int main(int argc, char *argv[]) 24 { 25 singleton *s = singleton::get_instance(); 26 return 0; 27 }
輸出:
[2]使用靜態的成員變數方式,第一次訪問的時候創建實例,並且添加了垃圾回收類:
1 #include <iostream> 2 #include <stdio.h> 3 using namespace std; 4 5 class singleton 6 { 7 public: 8 static singleton *get_instance(){ 9 if(m_instance == NULL){ 10 m_instance = new singleton(); 11 printf("get_instance() called.\n"); 12 } 13 14 return m_instance; 15 } 16 17 ~singleton(){ 18 printf("~singleton() called.\n"); 19 } 20 21 private: 22 singleton(){ 23 printf("singleton() called.\n"); 24 } 25 26 class gc 27 { 28 public: 29 gc(){ 30 printf("gc() called.\n"); 31 } 32 33 ~gc(){ 34 printf("~gc() called.\n"); 35 if(m_instance != NULL){ 36 delete m_instance; 37 m_instance = NULL; 38 } 39 } 40 }; 41 42 static gc m_gc; 43 static singleton *m_instance; 44 }; 45 46 singleton *singleton::m_instance = NULL; 47 singleton::gc singleton::m_gc; 48 49 int main(int argc, char *argv[]) 50 { 51 singleton *s = singleton::get_instance(); 52 return 0; 53 }
輸出:
4.說明:
[1]上面的兩種方式沒有好壞之分,只是不同的實現方式,其他還有各種方式實現單實例,但是都沒什麼區別。
[2]關於析構函數,因為private類型的析構函數無法在外部使用delete對象,所以準備在外面手動釋放這個類的實例和其他內部成員時,應該把析構函數設置為public,如果想讓這個類的所有成員必須在類內部釋放(類裡面的垃圾回收類中釋放),則應該把析構函數設置為private。