C++设计模式-单件

理解

1.       Singleton模式用来取代全局静态变量。C++通过静态成员变量来实现类实例全局唯一性。

2.       instance()方法是单件提供的唯一调用入口。

要点

1.       为了防止外界调用产生多个实例,将构造方法、析构方法、拷贝构造方法、赋值重载方法都作为protected。

2.       instance()方法产生对象方式有两种:使用局部static对象,生命期在首次进入局部生命期产生(见下面),在程序结束时销毁;通过new产生新对象,在析构方法中delete对象。

3.       获取单件实例调用方式:Singleton::instance()获取对象指针。

4.       解决多线程资源竞争条件。使用著名的“双检测锁定”办法来解决,即在锁定前和锁定后都检测对象是否产生,这样既能保证加锁效率又能保证单件实例的唯一性。

应用

1.       代码部分使用类模版单件(CSingleton<T>),可产生不同种类的单件类。

2.       一个类要成为单件类,把单件类作为自己的友元来实现,因为CSingleton的构造和析构都是protected(下面的例子);另外也有通过继承单件来实现。

3.       单件可以很简单实现,也可以足够复杂。Loki库实现了一个比较复杂的单件,将类型和各种策略(创建策略、生命期策略、线程策略等)作为模板参数,封装成了SingletonHolder类模板。详细可见:http://loki-lib.sourceforge.net/index.php?n=Pattern.Singleton

new产生新对象+友元实现的源码

 1 #include <iostream>
 2 using namespace std;
 3
 4 //////////////////Singleton定义
 5 /**
 6 * @class CSingleton
 7 * @brief 实现类把该类作为友元, 并且把构造函数作为非公有
 8 *         如:
 9 *          Class C
10 *          {
11 *          friend class CSingleton<C>;
12 *          protected:
13 *              C(){};
14 *          }
15 */
16 template<class T>
17 class CSingleton
18 {
19 public:
20     static T* instance()
21     {
22         //double check. 锁前和锁后检测,保证效率和多线程正确性
23         if (!m_pInstance)
24         {
25             CMutexGuard guard(m_lock);//TODO: 加锁.
26
27             if (!m_pInstance)
28             {
29                 //static T t;
30                 //m_pInstance = &t;
31                 m_pInstance = new T;
32             }
33         }
34         return m_pInstance;
35     };
36
37 protected:
38     CSingleton(){}; //防止产生实例
39     CSingleton(const CSingleton&){}; //防止拷贝构造另一个实例
40     CSingleton &operator =(const CSingleton&){}; //防止赋值构造出另一个实例
41     virtual ~CSingleton()
42     {
43         if (m_pInstance)
44         {
45             delete m_pInstance;
46             m_pInstance = NULL;
47         }
48     };
49
50 private:
51     static T* m_pInstance; //类的唯一实例
52     //TODO: 省略了互斥锁成员m_lock
53 };
54
55
56 //////////////////Singleton实现部分
57 template<class T> T* CSingleton<T>::m_pInstance = NULL;
58
59
60 /////////////////Singleton应用实例
61 class CMyLog
62 {
63
64 friend class CSingleton<CMyLog>; //作为友元可以访问CSingleton的保护成员
65
66 public:
67     void Log(char* pszStr)
68     {
69         cout << "Log msg: " << pszStr << endl;
70     }
71
72 private:
73     CMyLog(){}; //不允许直接实例化
74 };
75
76 int main()
77 {
78     CMyLog* pLog = CSingleton<CMyLog>::instance();
79     pLog->Log("hello word");
80
81     system("pause");
82     return 0;
83 } 

使用局部static对象方式

1  class CBz2Helper
2  {
3   static CBz2Helper& Instance()
4   {
5    static CBz2Helper Instance;
6    return Instance;
7   }
8
9  }
时间: 2024-11-10 08:01:46

C++设计模式-单件的相关文章

设计模式 - 单件模式(singleton pattern) 详解

单件模式(singleton pattern) 详解 本文地址: http://blog.csdn.net/caroline_wendy/article/details/28595349 单件模式(singleton pattern) : 确保一个类只有一个实例, 并提供一个全局访问点. 单价模式包括3个部分: 私有构造器, 静态变量, 静态方法. 具体方法: 1. 标准的单例模式: /** * @time 2014.6.5 */ package singleton; /** * @author

[设计模式]单件模式

单件模式确保一个类只有一个实例并提供一个全局访问点.实现起来也很简单,如果一个类只想有一个实例的话,那么这个类将构造函数私有化,并利用一个静态变量记录这个类的唯一实例,还要提供一个静态方法返回这个类的实例. 但是单件模式在多线程情况下可能会有些问题,解决方法一是使用同步方法返回实例,二是使用急切实例化,三是使用双重检查加锁,就是先检查实例,如果不存在就进入同步块. 类图: 参考:<Head First设计模式>

Java设计模式——单件模式

概述: 有一些对象其实我们只需要一个,比方说:线程池(threadpool).缓存(cache).对话框.处理偏好设置和注册表(registry)的对象.日志对象,充当打印机.显卡等设备的驱动程序的对象.事实上,这类对象只能有一个实例,如果制造出多个对象,就会导致许多的问题产生,例如:程序的行为异常.资源使用过量,或者是不一致的结果.--<Head First设计模式> 使用环境: 当我们的对象在逻辑上只能有一个的时候,比如说打印机.想像一下,如果我们有两个指向同一台打印机的对象,这时我们应该

[设计模式]单件模式概念和三个解决多线程问题的方案

主要是从 Head Fisrt 设计模式中学习到知识: 1. 定义单件模式 单件模式确保一个类只有一个实例,并提供一个全局访问点: 在整个系统上下文中,只有一个对象,对于很多在系统中只需要一个或者创建代价比较大的对象,可以使用,例如:线程池.缓存.对话框.处理偏好设置和注册表对象.日志对象.充当打印机.显卡等设备的驱动程序的对象: 采用单件模式可以避免系统维护太多没有记录状态数据.所有实例功能可替代的相关对象,还有就是多个实例处理会可能会造成结果不一致的问题: 2. 主要思想 2.1 由类持有一

说说设计模式~单件模式(Singleton)

单件模式(Singleton)要求一个类有且仅有一个实例,并且提供了一个全局的访问点. 从概念上来研究一下它的实现,不考虑线程安全 1 public sealed class Singlton 2 { 3 static Singlton instance = null; 4 private Singlton() { } 6 7 public static Singlton Instance 8 { 9 get 10 { 11 if (instance == null) 12 { 13 insta

设计模式 单件-Singleton

单件模式 Singleton 什么时候使用?当需要独一无二的对象时,请想起他. 举例:线程池(threadpool),缓存(cache),对话框,处理偏好设置和注册表(registry)的对象,驱动程序对象. 无需具体例子,先看类图:包含一个private的自己的实例.private的构造函数,确保无法在类以外创建.在getInstance()中检测私有实例是否创建,未则创建,若已存在则直接返回. 看代码更好理解记忆. 经典实现方式 Typical Singleton public class

《Head First 设计模式》学习笔记——单件模式

设计模式 单件模式:确保一个类只有一个实例,并提供一个全局访问点. 要点 单件模式确保程序中一个类最多只有一个实例. 在Java中实现单件模式需要私有的构造器.一个静态方法.一个静态变量. 确定在性能和资源上的限制,然后小心翼翼的选择适当的方案来实现单件,以解决多线程问题. 全局变量缺点 如果将对象赋值给一个全局变量,那么必须在程序一开始就创建好对象.万一对象非常耗费资源,而程序在这次执行过程中并没有使用它,就形成了浪费. 单件模式 public class Singleton { //利用一个

设计模式(博客园精化集)

Web Client Software Factory系列(3):View-Presenter模式作者: TerryLee .NET设计模式(18):迭代器模式(Iterator Pattern)作者: TerryLee .NET设计模式(19):观察者模式(Observer Pattern)作者: TerryLee .NET设计模式(2):单件模式(Singleton Pattern)作者: TerryLee .NET设计模式(3):抽象工厂模式(Abstract Factory)作者: Te

单例模式与多线程

概述 关于一般单例模式的创建和分析在我的另一篇博客<Java设计模式--单件模式>中有详细说明.只是在上篇博客中的单例是针对于单线程的操作,而对于多线程却并不适用,本文就从单例模式与多线程安全的角度出发,讲解单例模式在多线程中应该如何被使用. 版权说明 著作权归作者所有. 商业转载请联系作者获得授权,非商业转载请注明出处. 本文作者:Coding-Naga 发表日期: 2016年4月6日 本文链接:http://blog.csdn.net/lemon_tree12138/article/det