实现单例模式(offer)

来源:互联网 发布:sql 多个case when 编辑:程序博客网 时间:2024/06/16 09:11

题目:

设计一个类,我们只能生成该类的一个实例。

解答:
单例模式的类有以下几个特征:
1.构造函数是private。

2.有一个唯一实例的静态指针,且是private。

3.有一个public接口函数,获得该唯一实例的指针。

解法一:

按照上面的特征实现的单例类如下:

[cpp] view plain copy
  1. class Singleton{  
  2. public:  
  3.     static Singleton* getInstance();       //获得实例  
  4. private:  
  5.     Singleton();  
  6.     static Singleton* m_pInstance;         //static声明  
  7. };  
  8.   
  9. Singleton* m_pInstance = NULL;             //static定义  
  10. Singleton* getInstance()  
  11. {  
  12.     if (m_pInstance == NULL) m_pInstance = new Singleton();  
  13.     return m_pInstance;  
  14. }  
但是上述类存在static变量,如果在单线程模式下OK,但是在多线程模式下,就可能产生与初始化有关的“竞速形势”(条款04)。

条款04中提供了一种方法解决“竞速形势”,就是在程序的单线程启动阶段,手动调用所有reference-returning函数。这显然有点麻烦。
以后补充多线程安全的单例模式。


解法二:利用互斥锁

可以用一个互斥锁将该方法锁住,每次只能有一个线程访问该方法,缺点是加锁是耗时操作,效率较低。

[cpp] view plain copy
  1. class Singleton{  
  2. public:  
  3.     static Singleton* getInstance();       //获得实例  
  4. private:  
  5.     Singleton();  
  6.     static Singleton* m_pInstance;         //static声明  
  7. };  
  8.   
  9. Singleton* m_pInstance = NULL;             //static定义  
  10. Singleton* getInstance()  
  11. {  
  12.     lock(mutex){   //互斥锁  
  13.         if (m_pInstance == NULL) m_pInstance = new Singleton();  
  14.         return m_pInstance;  
  15.     }  
  16. }  
效率比这个高的是加锁前判断实例是否已经存在。
解法三(强烈推荐):利用静态构造函数(设计模式中的方法)

 其实一旦设置好m_pInstance就不需要同步了,因此提前创建实例,而不用延迟实例化的方法。

[cpp] view plain copy
  1. class Singleton{  
  2. private:  
  3.     Singleton();  
  4.     static Singleton* m_pInstance = new Singleton();         //static声明  
  5. public:  
  6.     static Singleton* getInstance(){ return m_pInstance; }       //获得实例  
  7. };  
可惜,上面会提示错误:a member with a in-class initializer must be const
改成下面这样可以:
[cpp] view plain copy
  1. class Singleton{  
  2. private:  
  3.     Singleton();  
  4.     static const Singleton* m_pInstance ;         //static声明  
  5. public:  
  6.     static const Singleton* getInstance(){ return m_pInstance; }       //获得实例  
  7. };  
  8.   
  9. const Singleton* Singleton::m_pInstance = new Singleton();  
原创粉丝点击