今天寫了一個單例模式的實現。代碼如下:
#include <iostream>
using namespace std;
//define CSingleton class
class CSingleton
{
private:
static CSingleton *m_pinstance;
CSingleton()
{
//m_pinstance=new CSingleton;//該類型語句爲嚴重錯誤,自己的構造函數new自己,將陷入死循環
cout<<"CSingleton constructor"<<endl;
m_n=0;//用於測試
}
class CGarbo// 它的唯一工作就是在析構函數中刪除 CSingleton 的實例
{
public:
~CGarbo()
{
if(CSingleton::m_pInstance)
delete CSingleton::m_pInstance;
}
};
static CGabor Garbo; // 定義一個靜態成員,程序結束時,系統會自動調用它的析構函數
public:
int m_n;
static CSingleton *Getinstance()
{
if(NULL==m_pinstance) m_pinstance = new CSingleton;
return m_pinstance;//如果是第一次進入該函數,m_pinstance將被賦予new後的新指針,否則都是和第一次時同一個值
}
//以下爲錯誤的析構函數,將出現自己析構自己的類型,陷入死循環
virtual ~CSingleton()
{
if(NULL!=m_pinstance)
{
cout<<"destructor CSingleton"<<endl;
delete m_pinstance; //此處嚴重錯誤,因爲m_pinstance爲指向CSingleton類型對象的指針
}
}
};
CSingleton* CSingleton::m_pinstance=NULL;
//CGabor CSingleton::Garbo=;
void main()
{
CSingleton *s1=CSingleton::Getinstance();
cout<<s1->m_n<<endl;
s1->m_n=100;
CSingleton *s2=CSingleton::Getinstance();
cout<<s2->m_n<<endl;//若此處輸出100則證明s1和s2指向同一個實例
}
幾個注意的地方:
1、定義了一個私有的靜態對象指針:static CSingleton *m_pinstance,目的是爲了使其指向唯一的實例對象(該類類型指針),並可以從它判斷出是否已經有實例對象(靜態),並防止其他地方濫用(私有);
2、定義了一個私有的構造函數,防止外部調用以構造多個對象;
3、定義了一個公有靜態函數,並返回CSingleton類型的指針,可以獲取這個唯一的實例(返回值),並根據判斷私有靜態指針的值創建該實例(內部new,調用私有構造函數),而且該函數必須爲靜態,否則在外部無法調用它;
4、特別注意:在該類的構造函數和析構函數中,不可以出現自己的構造函數裏面出現new自己或者析構函數中出現delete自己類型的指針的情況,否則出現死循環。