c++ 中的单例类模板的实现方法

 一、什么是单例模式

  在架构设计时,某些类在整个系统生命周期中最多只能有一个对象存在 ( Single Instance )。如超市收银系统,其外观主要由显示器(1个)、扫描枪(1个)、收款箱(1个)组成,在系统正常运行期间这三部分都是惟一存在的;也就是说,显示器、扫描枪、收款箱这三部分都应该有各自的类,而且每一个类只能惟一地实例化一个对象,基于这种模式的程序设计,称为单例模式。ios

  !!!单例模式只能建立一个对象,且该对象的生命周期伴随系统的整个运行期间。架构

二、怎么实现单例模式

  思考:如何定义一个类,使得这个类最多只能建立一个对象?ide

  分析:由于对象是由构造函数建立的,因此咱们应该将问题锁定在构造函数上;又由于只能建立一个对象,这就意味着只能调用一次构造函数;显然将构造函数的访问权限设置为 public 不合适,因此,构造函数的访问权限只能是 private。而后,定义一个私有的静态成员 c_instance = NULL 和 公有的静态成员函数,经过  c_instance 来判断是否建立对象。(这个为何要使用 静态成员呢?由于构造函数是私有的,在类的外部没法建立对象,只能经过类名调用静态成员,而静态成员函数只能调用静态成员变量) 函数

  上述分析过程可简化为:测试

  (1)将构造函数的访问属性设置为 private;this

  (2)定义私有的静态成员属性 instance 并初始化为 NULL;spa

  (3)当须要使用对象时,访问 instance 的值;架构设计

           1)空值:建立对象,并用 instance 标记;设计

           2)非空值:返回 instance 标记的对象;指针

 1 #include <iostream>
 2 #include <string>
 3 
 4 using namespace std;
 5 
 6 class SObject
 7 {
 8     static SObject* c_instance;  // 定义标识符指针;
 9 
10     /* 不需用拷贝和赋值,在单例模式中,始终只有一个对象 */    
11     SObject(const SObject&);
12     SObject& operator= (const SObject&);
13     
14     SObject()  // 私有的构造函数
15     {
16     }
17 public:
18     static SObject* GetInstance();    // 建立对象的入口
19     
20     void print()
21     {
22         cout << "this = " << this << endl;
23     }
24 };
25 
26 SObject* SObject::c_instance = NULL; // 静态成员类内声明,类外定义
27 
28 SObject* SObject::GetInstance() // 单例模式的关键
29 {
30     if( c_instance == NULL )
31     {
32         c_instance = new SObject();
33     }
34     
35     return c_instance;
36 }
37 
38 int main()
39 {
40     SObject* s = SObject::GetInstance();
41     SObject* s1 = SObject::GetInstance();
42     SObject* s2 = SObject::GetInstance();
43     
44     s->print();    // this = 0x940a008
45     s1->print();  // this = 0x940a008
46     s2->print();  // this = 0x940a008
47     
48     return 0;
49 }
50 // 注:单例模式中,对象的生命周期存在整个系统运行过程当中,因此是绝对不释放的;
单例模式实现

 ·   其实,在上述的单例模式实现案列中,有一部分代码(分析过程当中第二、3步)与类自己没有任何关系,既然是这样,咱们就把这部分单独提取出来处理。

  问题所在:须要使用单例模式时,必须在每一个类中定义 静态成员变量 c_instance 和 静态成员函数 GetInstance();当有多个类都须要使用单例模式时,这样的实现方式明显的很冗余,为了可以代码复用,咱们能够 将这两部分抽象成一个新类(作成类模板,声明为其它类的友元类,这样与以前的效果同样)。

 1 // 对上个单例模式实现代码的改进
 2 
 3 // singleton.hpp 单例模式代码
 4 #ifndef SINGLETON_H
 5 #define SINGLETON_H
 6 
 7 template
 8 < typename T >
 9 class Singleton
10 {
11     static T* c_instance;
12 public:
13     static T* GetInstance();
14 };
15 
16 template
17 < typename T >
18 T* Singleton<T>::c_instance = NULL;
19 
20 template
21 < typename T >
22 T* Singleton<T>::GetInstance()
23 {
24     if( c_instance == NULL )
25     {
26         c_instance = new T();
27     }
28     
29     return c_instance;
30 }
31 
32 #endif
33 
34 // main.cpp 测试文件
35 #include <iostream>
36 #include <string>
37 #include "singleton.hpp"
38 
39 using namespace std;
40 
41 class SObject
42 {
43     friend class Singleton<SObject>;    // 当前类须要使用单例模式
44     
45     SObject(const SObject&);
46     SObject& operator= (const SObject&);
47     
48     SObject()
49     {
50     }
51 public:
52     
53     void print()
54     {
55         cout << "this = " << this << endl;
56     }
57 };
58 
59 int main()
60 {
61     SObject* s = Singleton<SObject>::GetInstance();
62     SObject* s1 = Singleton<SObject>::GetInstance();
63     SObject* s2 = Singleton<SObject>::GetInstance();
64     
65     s->print();    // 0xe63c20
66     s1->print();  // 0xe63c20
67     s2->print();  // 0xe63c20
68     
69     return 0;
70 }
基于类模板的单例模式实现

  在从此工做中,若是一个类(SObject)要使用单例模式(Singleton 单例模式的类模板),只需三步骤:

  (1)类(SObject)的构造函数必须私有化;同时,拷贝构造函数、重载=操做符 也私有化;

  (2)将单例模式的类模板声明为这个类的友元类; friend class Singleton<SObject>; 

  (3)经过 单例模式类模板中 SObject* s = Singleton<SObject>::GetInstance(); 建立对象。

相关文章
相关标签/搜索