单实例设计模式的实现
单实例设计大概是利用最遍及的设计模式。其思想意图是担保一个类只有一个实例,而且提供类工具的全程会见。单实例工具应用的范畴很广:如GUI应用必需是单鼠标,MODEM的联接需要一条且只需要一条电话线,操纵系统只能有一个窗口打点器,一台PC连一个键盘。本文将接头如何用C++实现单实例模式,并表明如何优化单线程应用的设计。
设计方案
利用全程工具可以或许担保利便地会见实例,可是不能担保只声明一个工具-也就是说除了一个全程实破例,仍然能建设沟通类的当地实例。单实例模式通过类自己来打点其独一实例,这种特性提供了问题的办理步伐。独一的实例是类的一个普通工具,但设计这个类时,让它只能建设一个实例并提供对此实例的全程会见。独一实例类Singleton在静态成员函数中埋没建设实例的操纵。习惯上把这个成员函数叫做Instance(),它的返回值是独一实例的指针。Singleton的界说如下:
class Singleton
{
public:
static Singleton* Instance();
protected:
Singleton();
Singleton(const Singleton&);
Singleton& operator= (const Singleton&);
private:
static Singleton* pinstance;
};
你还可以建设诸如Mouse,FileManager,Scheduler等为名字的类并声明相应的成员。为了担保用户不能建设类的当地实例,Singleton的结构器是赋值操纵符,结构函数的副本被声明为protected。类中还声明白一个私有的静态实例指针。当第一次挪用静态函数Instance()时,它建设独一实例,将实例地点赋值给pinstance,然后返回这个地点。在每次并发挪用中,Instance()也将只返回这个地点。
下面是类的实现:
Singleton* Singleton::pinstance = 0;// 初始化指针
Singleton* Singleton::Instance ()
{
if (pinstance == 0) // 是第一次挪用吗?
{
pinstance = new Singleton; // 建设独一实例
}
return pinstance; // 独一实例的地点
}
Singleton::Singleton()
{
//... 实现须要的实例初始化
}
用户会见独一实例的要领只有Instance()成员函数。假如不通过这个函数,任何建设实例的实验都将失败,因为类的结构函数是被掩护的。Instance()利用懒惰初始化,也就是说它返回的值是当这个函数被首次会见时被建设的。这是一种防弹设计-所有Instance()之后的挪用都返回沟通实例的指针:
Singleton *p1 = Singleton::Instance();
Singleton *p2 = p1->Instance();
Singleton & ref = * Singleton::Instance();
固然本文的例子针对的是单实例,但对Instance()稍加修改,这个设计模板便可合用于可变多实例环境。如一个类答允最多五个实例。
优化Singleton类,使之合用于单线程应用
Singleton利用操纵符new为独一实例分派存储空间。因为new操纵符是线程安详的,在多线程应用中你可以利用此设计模板。可是有一个缺陷:就是在应用措施终止之前必需手工用delete摧毁实例。不然,不只导致内存溢出,还要造成不行预测的行为,因为Singleton的析构函数将基础不会被挪用。而通过利用当地静态实例取代动态实例,单线程应用可以很容易制止这个问题。以下是与上面的Instance()稍有差异的实现,这个实现专门用于单线程应用:
Singleton* Singleton::Instance ()
{
static Singleton inst;
return &inst;
}
当地静态工具实例inst是第一次挪用Instance()时被结构,一直保持勾当状态直到应用措施终止。指针pinstance变得多余并可以从类界说中删除去。与动态分派工具差异,静态工具当应用措施终止时被自动销毁掉,所以就不必再手动销毁实例了。