• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

cynchanpin

  • 博客园
  • 联系
  • 订阅
  • 管理

View Post

“仅仅生一个娃”--设计模式中的单例模式

“仅仅生一个娃”–设计模式中的单例模式(Singleton)

  • 引言
      被人问到什么是单例模式,突然回答不上来,似乎印象不深了。

    回去补了一下功课,突然明确了,原来在项目中一直使用的日志模块即採用了单例模式,仅仅是熟视无睹,没有意识到罢了。
      所谓单例模式(Singleton),即指一个类仅仅有一个实例(Instance),并给外界提供訪问该实例的一个全局訪问点。
      通常我们能够使用全局变量的方式来实现“仅仅生一个娃”,但更好的方法就是:让该类自身负责创建和保存它的唯一实例。这个类能够保证没有其它实例能够被创建,而且对外提供一个訪问该实例的方法。以下我们看一下详细实现。

  • 单例模式实现
      定义一个Singleton类。加入一个静态方法GetInstance,负责创建自己的唯一实例,并供client訪问。

class Singleton  
{  
private:  
    Singleton()  
    {  
    }  
    static Singleton *m_pInstance;  

public:  
    static Singleton * GetInstance()  
    {  
        if(m_pInstance == NULL)  //若不存在,则new一个新的实例。  
                m_pInstance = new Singleton();  
        return m_pInstance;  
    }

    //能够定义一个详细干活的方法
    void DoWork()
    {
        printf("the work is done!");   
    }  
}; 

  注意:构造函数设为private。这样外界就不能通过new操作符来实例化该类。
  client訪问方法:

Singleton* p1 = Singleton :: GetInstance();
Singleton* p2 = p1->GetInstance();
Singleton & ref = * Singleton :: GetInstance();

p1->DoWork();
p2->DoWork();
ref.DoWork();
Singleton :: GetInstance()->DoWork();
  • 问题讨论
    多线程环境下。假设多个线程同一时候訪问Singleton类的GetInstance方法,则有可能造成创建多个实例。因此应该进行加锁保护,能够使用lock机制。确保当一个线程位于代码的临界区时。还有一个线程假设訪问可被堵塞等待,不进入临界区。能够这样来实现:
class Singleton  
{  
private:  
    Singleton()  
    {  
    }  
    static Singleton *m_pInstance;
    CCriticalSection m_cs;   //定义一个临界区对象
public:  
    static Singleton * GetInstance()  
    {  
        if(NULL == m_pInstance)  //若不存在,则new一个新的实例。  
        {
            lock(m_cs)         //尽在实例未被创建时进行加锁处理
          {
              

posted on 2017-05-04 19:56  cynchanpin  阅读(193)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3