問題:單例模式中,靜態函數中實例化了類對象,私有構造函數得到執行。構造函數是非靜態成員函數,難道靜態函數中能調用非靜態函數嗎?
class Singleton
{
public:
static Singleton * getInstance();
private:
Singleton();
~Singleton();
static Singleton * m_sglton ;//(此處也可直接寫為靜態變量)
};
Singleton* Singleton:: m_sglton = NULL;
- Singleton *Singleton::getInstance()
{
if(m_sglton == NULL)
{
m_sglton = new Singleton; //注意這一句
}
return sglton;(返回對象)
}
下面來分析下原因。
在開始正文之前,先復習一下C++靜態成員
因為靜態成員是與類相關聯的,非靜態成員是與對象相關聯的。靜態成員被所有對象共同擁有,且只有一份。靜態數據成員不包含在任何一個對象內。靜態成員函數不會隱式傳入this,所以靜態成員函數不能訪問類的非靜態成員。
在單例模式中,我們發現利用靜態成員函數調用中實例化了一個所屬類的對象,且該類的構造函數為私有函數。
注意有個錯誤的說法:靜態成員函數只可以訪問靜態成員變量/靜態成員函數不能訪問非靜態成員。靜態函數沒有默認的this對象指針。但是可以通過其他方式傳入對象的地址,便可以在靜態成員函數中訪問到非靜態成員函數。這種說法不夠嚴密。僅僅是不能在靜態成員函數中,使用this隱式或者顯式調用非靜態成員。因為靜態函數不與對象綁定在一起,因此也不能聲明成const的。
首先需要明確兩點:
1、因為構造函數是私有的,要實例化該對象,就要訪問類的私有域。而訪問私有域必須在類的內部進行(即在class成員中)。但是在沒有進行實例化之前,怎么能使用他的成員呢?----公有的靜態成員函數可以做到。
2、經過測試,通過靜態成員函數,可以調用私有的構造函數。
以上兩點滿足了單例模式才產生了!