zoukankan      html  css  js  c++  java
  • 设计模式之单例模式(c++)

     1、什么是单例模式

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

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

    2、怎么实现单例模式

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

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

      上述分析过程可简化为:

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

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

      (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 // 注:单例模式中,对象的生命周期存在整个系统运行过程中,所以是绝对不释放的;
    单例模式实现

     ·   其实,在上述的单例模式实现案列中,有一部分代码(分析过程中第2、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(); 创建对象。

     

  • 相关阅读:
    吴恩达 机器学习EX1学习笔记 MATLAB实现
    二分法解具有单调性的方程
    利用new定位运算符进行高效的数组动态增扩
    单循环链表基本操作及部分可能出现的细节问题
    数组中某元素的删除
    C# 实现可克隆(ICloneable)的类型
    Python学习十三
    Python学习十二
    Python学习十一
    Python学习十
  • 原文地址:https://www.cnblogs.com/nbk-zyc/p/12439146.html
Copyright © 2011-2022 走看看