近日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类的构造函数是私有的,为何在类外部还能直接调用?