实战设计模式系列-Singleton(单件)

【引言】

 

    单件模式的应用场景大家都不陌生,目的也很明确,就是一个类保证只有一个实际,比如项目中的资源管理器,或打log的类,都比较适合单件模式,话不多说,先贴一段代码吧。

 

 

 

class Singleton { public: static Singleton* Instance(); static void Destroy(); virtual void Print(); protected: Singleton(); private: static Singleton* _instance; }; Singleton* Singleton::_instance = 0; Singleton* Singleton::Instance() { if (_instance == 0) //线程不安全 { _instance = new Singleton; } return _instance; } void Singleton::Destroy() { if (_instance != 0) { delete _instance; _instance = 0; } } Singleton::Singleton() { printf("Create Singleton/n"); } void Singleton::Print() { printf("Singleton Print/n"); } int main(void) { Singleton::Instance()->Print(); return 0; }

 

    

    上面的实现是GOF中的标准实现,但是这种方案有些问题,如下所示:

 

    1. 不是线程安全的,如果两个线程A、B,A先调用if(_instance==0),这里判断结果是单件未实例化,这时cpu被B抢占,B也执行到同一行,判断结果也是未实例化,那么继续执行,_instance就会被实例化两次。

 

    2. 在全局变量或静态变量中调用单件模式的接口,比如上面的单件有个接口是int GetId(); 那可以定义一个全局的ID,如下所示: int g_Id = Singleton::Instance()->GetId(); 这时全量变量g_Id和静态变量_instance之间就存在一个初始化先后的问题,而C++并未对这类非局部静态变量初始化顺序做说明。

 

    针对上面的问题,给出一种改进的实现。

 

    【改进方案】

 

    下面的实现是采用静态局部变量的方案,保证在进程的生命周期中只实例化一次,如下所示:

 

class Singleton { public: static Singleton* Instance(); virtual void Print(); protected: Singleton(); }; Singleton* Singleton::Instance() { statice Singleton _instance; return &_instance; } Singleton::Singleton() { printf("Create Singleton/n"); } void Singleton::Print() { printf("Singleton Print/n"); } int main(void) { Singleton::Instance()->Print(); return 0; }

你可能感兴趣的:(设计模式,c,delete,Class)