近日SA老師佈置作業,讓我們分別用C#,C++實現幾種設計模式,其中一個是Singleton模式,我一開始寫的代碼如下:
#include <iostream>
#include <string>
using namespace std;
class Singleton {
public :
static Singleton* getInstance() {
if (0 == _instance)
_instance = new Singleton();
return _instance;
}
private :
Singleton(){};
static Singleton* _instance;
};
void main(){
cout<<"Start.";
Singleton *obj1 = Singleton::getInstance();
Singleton *obj2 = Singleton::getInstance();
if(obj1 == obj2)
cout<<"obj1和obj2是同一對象實例。";
else
cout<<"obj1跟obj2並非同一對象實例。";
}
這個代碼編譯可以通過,但是在連接是,出現錯誤:error LNK2019: 無法解析的外部符號 "public: static class Singleton * Singleton::_instance" (?_instance@Singleton@@2PAV1@A),該符號在函數 "public: static class Singleton * __cdecl Singleton::getInstance(void)" (?getInstance@Singleton@@SAPAV1@XZ) 中被引用
D:/Visual Studio 2005/Projects/SA/Lab1/Singleton_C++/Release/Singleton_C++.exe : fatal error LNK1120: 1 個無法解析的外部命令
查了很多資料,均無法解決問題,而且網上都是說類中的靜態函數,無法引用非靜態成員,但是可以引用靜態成員。後來修改代碼如下,MAIN函數不變:
#include <iostream>
#include <string>
using namespace std;
class Singleton {
public :
static Singleton* getInstance() {
static Singleton* _instance;
if (0 == _instance)
_instance = new Singleton();
return _instance;
}
private :
Singleton(){};
};
就沒錯誤可以執行,心中很是奇怪,思考之後,覺得應該是靜態成員的生命必須放在靜態函數中,但這個想法馬上被否決了。後來在網上看別人代碼發現:
類的靜態成員是一開始就需要被初始化,分配內存空間,才能被靜態調用,而類的普通成員是在類聲明對象後才分配內存空間,以上錯誤就是在未給靜態成員分配空間時,就調用它,系統無法識別。後來,根據這個原因,修改代碼如下,MAIN函數不變:
class Singleton {
public :
static Singleton* getInstance() {
if (0 == _instance)
_instance = new Singleton();
return _instance;
}
static Singleton* _instance;
private :
Singleton(){};
};
Singleton* Singleton::_instance = 0;
依然可以執行,
然後又把Singleton* Singleton::_instance = 0;這句改爲Singleton* Singleton::_instance = new Singleton();
依然可以執行,不過有個新的問題:Singleton類的構造函數是私有的,爲何在類外部還能直接調用?