singleton模式引出的static错误

今天在看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变量拷贝。

Posted in: c++

2 thoughts on “singleton模式引出的static错误”

发表评论

电子邮件地址不会被公开。 必填项已用*标注