今天在看c++中单体模式的实现时,出现了一个这样的错误
下面先列一下单体模式的代码
#include
using namespace std;
class Singleton
{
public:
static Singleton * Instance()
{
if(_instance==0)
_instance = new Singleton;
return _instance;
}
private:
Singleton(void)
{
}
virtual ~Singleton(void)
{
}
static Singleton* _instance ;
};
int main()
{
Singleton*s1 = Singleton::Instance();
Singleton*s2 = Singleton::Instance();
if(s1 = s2)
cout<<"they are same object";
}
在编译这段代码的时候,一直报错
nresolved external symbol "private: static class Singleton * Singleton::_instance" (?_instance@Singleton@@0PAV1@A)
后来发现这是由于static Singleton* _instance ;这个static变量没有初始化的缘故。
查了资料发现,static变量必须在类定义的时候进行初始化
#include
using namespace std;
class Singleton
{
public:
Singleton()
{}
public :
static int a;
};
int main()
{
cout<
测试上面代码,还是会报错,验证了我的想法。在c++标准中,static const int型必须在类定义内部进行初始化,但在vc6.0中不支持,vs2010中支持。注意这里是 static const int,其他比如static const double都在类外部初始化。
回到主题,在加上
Singleton* Singleton::_instance = NULL;
这句话后,单体模式便可以运行了。
同时,在网上又看到另一种方法
#include
using namespace std;
class Singleton
{
public:
static Singleton * Instance()
{
static Singleton* _instance ;
_instance = new Singleton;
return _instance;
}
private:
Singleton(void)
{
}
virtual ~Singleton(void)
{
}
};
int main()
{
Singleton*s1 = Singleton::Instance();
Singleton*s2 = Singleton::Instance();
if(s1 = s2)
cout<<"they are same object";
}
由于我们可能频繁的调用,所以为了提高效率将Instance函数改为
static Singleton * Instance()
{
static Singleton singleton;
return &singleton;
}
这里巧妙的运用了编译器的特性:即函数内的static对象只在该函数第一次执行时才初始化(请注意不是static常量。
还有一个问题便是
static变量继承出现的。
在继承中,static变量不会给子类一份拷贝,而是继续保持父类的。看下面的程序
#include
using namespace std;
class Base{
static int itest;
public:
void Set(){
itest++;
}
void Show(){
cout << itest << endl;
}
};
int Base::itest = 100;
class Derive: public Base{
};
class Derive2: public Base{
};
int main(int argc, char* argv[])
{
Derive d1;
Derive2 d2;
d1.Set();
d2.Set();
d1.Show();
d2.Show();
return 0;
}
说明了子类的静态变量与父类共用。所有的派生类与基类共享一份static变量空间。
那么如何让子类拥有自己的static变量呢?
答案是用template类
#include
using namespace std;
template< typename _class >
class Base{
static int itest;
public:
void Set(){
itest++;
}
void Show(){
cout << itest << endl;
}
};
template < typename _class >
int Base< _class >::itest = 100;
class Derive: public Base{
};
class Derive2: public Base{
};
int main(int argc, char* argv[])
{
Derive d1;
Derive2 d2;
d1.Set();
d2.Set();
d1.Show();
d2.Show();
return 0;
}
这段程序中父类用了模板类,当子类继承父类的时候,指定了不同的类型,所以子类继承的是不同的父类,所以会为子类保存不同的static变量拷贝。
Incredible! This can be just one of the very most practical web logs We’ve appear all around for this topic area. Simply Awesome. I will be fashionable specific in such a topic thus i can easily have an understanding of your effort.
thank you ,I will keep this spirit always.