昨天面試的時候,面試官讓我用C++或Java實現一個單例模式。
因為設計模式是在12年的時候學習過這門課,而且當時覺得這門課很有意思,所以就把課本讀了幾遍,所以印象比較深刻,但是因為實際編程中很少注意使用,所以沒能編碼實現。
這是之前用C#寫的一個單例模式的文章:http://www.cnblogs.com/CheeseZH/archive/2012/05/14/2500546.html
什么是單例模式
單件模式(SingletonPattern):確保一個類只有一個實例,並提供一個全局訪問點。和全局變量一樣方便,又沒有全局變量的缺點,即不需要從一開始就創建對象,而是在需要時才創建它。
那么要如何保證一個類只能被實例化一次呢?一般情況下,如果存在一個類,我們都是可以多次地實例化它的。那么如果這樣呢:
1 public MyClass{ 2 private MyClass(){ 3 } 4 }
咦?構造函數私有?含有私有的構造器的類應該是不能被其他類實例化的,因為只有MyClass內部的代碼才能調用這個私有的構造函數。雖然只有MyClass類的實例才能調用MyClass構造器,但在這之前,必須有一個MyClass實例。然而這個類又不能被實例化,這樣就產生了矛盾!
看下面這段代碼:
1 public MyClass{ 2 public static MyClass getInstance(){ 3 } 4 }
上面的代碼表示MyClass有一個靜態方法,我們可以這樣調用這個方法:MyClass.getInstance(); 因為getInstance()是一個靜態方法,換句話說,是一個“類”方法。引用一個靜態方法,你需要使用類名,而不是對象名。
那么把上面兩段代碼合在一起,是否就可以使MyClass只產生一個實例了呢?
看下面的代碼:
1 public class MyClass{ 2 //利用一個靜態變量來記錄MyClass類的唯一實例 3 private static MyClass uniqueInstance; 4 //私有構造函數,只有自MyClass類內才可以調用 5 private MyClass() {} 6 //用getInstance靜態方法實例化對象,並返回 7 public static MyClass getInstance(){ 8 if(uniqueInstance == NULL) 9 { 10 uniqueInstance = new MyClass(); 11 } 12 return uniqueInstance; 13 } 14 //當然,單件類也是一個正常的類,具有其他的變量和方法 15 //... 16 }
這就是一個經典的單件模式的實現!之所以實例唯一,是因為單件類沒有公開的構造器,其他類不能自行將其實例化得到一個實例,而必須通過它的靜態方法getInstance()去創建一個實例。
C++完整實現
Singleton.h
1 #pragma once 2 3 class Singleton{ 4 private: 5 Singleton(); 6 ~Singleton(); 7 static Singleton* uniqueInstance; 8 9 public: 10 static Singleton* getInstance(); 11 // other methods... 12 };
Singleton.cpp
1 #include"Singleton.h" 2 #include<iostream> 3 using namespace std; 4 5 Singleton::Singleton(){ 6 7 } 8 9 Singleton::~Singleton(){ 10 if(uniqueInstance == NULL){ 11 return; 12 } 13 delete uniqueInstance; 14 uniqueInstance = 0; 15 } 16 17 Singleton* Singleton::getInstance(){ 18 if(uniqueInstance == NULL){ 19 uniqueInstance = new Singleton; 20 } 21 return uniqueInstance; 22 }
main.cpp
1 #include<iostream> 2 #include"Singleton.h" 3 using namespace std; 4 5 Singleton* Singleton::uniqueInstance = NULL; 6 7 int main(){ 8 Singleton* singleton1 = Singleton::getInstance(); 9 Singleton* singleton2 = Singleton::getInstance(); 10 if(singleton1 == singleton2){ 11 cout<<"Got same singleton!!"<<endl; 12 } 13 else{ 14 cout<<"Oh,no!got a different singleton!!"<<endl; 15 } 16 return 0; 17 }
一個完整的單例模式代碼:
1 #include<iostream> 2 using namespace std; 3 class CSingleton 4 { 5 private: 6 CSingleton() { 7 } 8 ~CSingleton() { 9 if (m_pInstance == NULL) { 10 return; 11 } 12 delete m_pInstance; 13 m_pInstance = NULL; 14 } 15 static CSingleton *m_pInstance; 16 public: 17 static CSingleton * GetInstance() { 18 if(m_pInstance == NULL) 19 m_pInstance = new CSingleton(); 20 return m_pInstance; 21 } 22 }; 23 CSingleton* CSingleton::m_pInstance = NULL;//類的靜態成員變量需要在類外邊初始化 24 25 int main() { 26 27 CSingleton* single1 = CSingleton::GetInstance(); 28 CSingleton* single2 = CSingleton::GetInstance(); 29 30 if (single1 == single2) { 31 cout<<"Same"<<endl; 32 } 33 return 0; 34 }