到底是用singleton 还是 全局对象?看了一些文章,但是还是不是很清晰。自己整理一下。
singleton特点: 1 使用时分配,如不使用则不分配。
2 保证全局只有唯一对象
全局对象特点: 1 应用程序初始化时分配 结束时销毁
2 可以生成新的类的对象
我觉得考虑这一点: 全局的引用数量是否会经常变成0。如果这样的话,singleton模式会经常创建和销毁对象,产生不必要的额外开销。而如果可以认为基本上全局引用数量不会为零,即必然会引用,那么推迟初始化有什么意义呢?我认为在这一点上,只有下面2种情况下 singleton才优于 全局对象: 1该对象要么引用数为0,一但引用数多于0,那么会保持很长时间不会变为0。2系统对空间要求高,对时间要求低。即需要拿时间换取空间。
而另外一点,singleton可以保证全局只有一个该类的实例,而全局对象不可以。最初我认为这是一个很好的模式。但后来经过仔细思考后发觉,singleton似乎没有用。singleton保证全局唯一实例的目的在于什么?在于保证开发者不会无意的用该类生成其它实例。singleton是通过私有化构造函数来实现的。我有一个方法,是使用一个静态成员函数记录生成对象数,并在初始化时考察该数量,如果该数量大于1,则抛出异常。这样来保证系统中只有唯一该类的实例。下面是示例代码:
#include <exception>
#include <iostream>
#include <assert.h>
class AA{
public:
AA()
{
nRef++;
assert(nRef==1);
}
static int nRef;
};
int AA::nRef=0;
public:
AA()
{
nRef++;
assert(nRef==1);
}
static int nRef;
};
int AA::nRef=0;
int main()
{
cout<<"beforea1"<<endl;
AA a1;
cout<<"beforea2"<<endl;
AA a2;
cout<<"beforea3"<<endl;
AA a3;
cout<<"after all"<<endl;
}
{
cout<<"beforea1"<<endl;
AA a1;
cout<<"beforea2"<<endl;
AA a2;
cout<<"beforea3"<<endl;
AA a3;
cout<<"after all"<<endl;
}
运行结果如下
beforea1
beforea2
beforea2
a.out: a.cpp:10: AA::AA (): Assertion `nRef==1' failed.
Aborted
Aborted
显然在构造第二个对象的时候产生了异常。
相比之下,singleton是编译时保证全局唯一性,我的方法(暂时自称 Init Singleton 模式)是在运行时保证全局的唯一性。而同时兼有全局对象用法的优点。
在这里提出这种模式供大家讨论。