前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >实战设计模式系列-Singleton(单件)

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

作者头像
王亚昌
发布2018-08-03 15:35:49
4160
发布2018-08-03 15:35:49
举报
文章被收录于专栏:王亚昌的专栏

【引言】

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

代码语言:javascript
复制
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++并未对这类非局部静态变量初始化顺序做说明。

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

    【改进方案】

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

代码语言:javascript
复制
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;  
}  
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2010年04月28日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档