实现单例模式C++版本

还是先看最简单的C++单例模式

class CSingleton
{
private:
	CSingleton(){}
	static CSingleton *pInstance;

public:
	static CSingleton* getInstance()
	{
		if(pInstance == NULL)
		{
			pInstance = new CSingleton();
		}
		return pInstance;
	}
};

  大多数时候,这样的实现都不会出现问题。有经验的读者可能会问,m_pInstance指向的空间什么时候释放呢?更严重的问题是,该实例的析构函数什么时候执行?
如果在类的析构行为中有必须的操作,比如关闭文件,释放外部资源,那么上面的代码无法实现这个要求。我们需要一种方法,正常的删除该实例。
可以在程序结束时调用GetInstance(),并对返回的指针掉用delete操作。这样做可以实现功能,但不仅很丑陋,而且容易出错。因为这样的附加代码很容易被忘记,而且也很难保证在delete之后,没有代码再调用GetInstance函数。
一个妥善的方法是让这个类自己知道在合适的时候把自己删除,或者说把删除自己的操作挂在操作系统中的某个合适的点上,使其在恰当的时候被自动执行

我们知道,程序在结束的时候,系统会自动析构所有的全局变量。事实上,系统也会析构所有的类的静态成员变量,就像这些静态成员也是全局变量一样。利用这个特征,我们可以在单例类中定义一个这样的静态成员变量,而它的唯一工作就是在析构函数中删除单例类的实例。

class CSingleton
{
private:
	CSingleton(){}
	static CSingleton *pInstance;

	class CGarbo//它的唯一工作就是在析构函数中删除CSingleton的实例
	{
	public:
		~CGarbo()
		{
			if(pInstance)
			{
				delete pInstance;
			}
		}
	};
	static CGarbo garbo;//定义一个静态成员变量,程序结束时,系统会自动调用它的析构函数

public:
	static CSingleton* getInstance()
	{
		if(pInstance == NULL)//判断是否第一次调用
		{
			pInstance = new CSingleton()
		}

		return pInstance;
	}
};

类CGarbo被定义为CSingleton的私有内嵌类,以防该类被在其他地方滥用。
程序运行结束时,系统会调用CSingleton的静态成员Garbo的析构函数,该析构函数会删除单例的唯一实例。
使用这种方法释放单例对象有以下特征:
在单例类内部定义专有的嵌套类;
在单例类内定义私有的专门用于释放的静态成员;
利用程序在结束时析构全局变量的特性,选择最终的释放时机;
使用单例的代码不需要任何操作,不必关心对象的释放。

使用局部静态变量,非常强大的方法,完全实现了单例的特性,而且代码量更少,也不用担心单例销毁的问题。
但使用此种方法也会出现问题,当如下方法使用单例时问题来了,
Singleton singleton = Singleton :: GetInstance();
这么做就出现了一个类拷贝的问题,这就违背了单例的特性。产生这个问题原因在于:编译器会为类生成一个默认的构造函数,来支持类的拷贝。

最后没有办法,我们要禁止类拷贝和类赋值,禁止程序员用这种方式来使用单例。

class CSingleton
{
private:
    CSingleton()   //构造函数是私有的
    {
    }
    CSingleton(const CSingleton &);
    CSingleton & operator = (const CSingleton &);
public:
    static CSingleton & GetInstance()
    {
        static CSingleton instance;   //局部静态变量
        return instance;
    }
};

  这时的拷贝构造函数和赋值拷贝构造函数需要声明成私有的,并且只声明不实现。这样,如果在外部通过构造函数、拷贝构造函数、赋值拷贝构造函数等新建实例都会产生编译器错误。如果类的成员函数或者友元函数创建实例会引起连接器的错误。

到这里还是单线程的模式,如果想在多线程下运行,还必须想上一篇C#版本的单例模式一样,利用同步锁。

Singleton* Singleton::Instantialize()
{
    if(pInstance == NULL)
    {   //double check
        Lock lock(cs);           //用lock实现线程安全,用资源管理类,实现异常安全
        //使用资源管理类,在抛出异常的时候,资源管理类对象会被析构,析构总是发生的无论是因为异常抛出还是语句块结束。
        if(pInstance == NULL)
        {
            pInstance = new Singleton();
        }
    }
    return pInstance;
}

  

时间: 2024-08-24 13:19:02

实现单例模式C++版本的相关文章

设计模式-06 单例模式(创建型模式)

一 单例模式 单例模式(Singleton Pattern)提供了一种创建对象的最佳方式.这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建.这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象. 主要解决: 一个全局使用的类频繁地创建与销毁. 关键代码: 构造函数是私有的. 使用场景: Windows 是多进程多线程的,在操作一个文件的时候,就不可避免地出现多个进程或线程同时操作一个文件的现象,所以所有文件的处理必须通过唯一的实例来进行. 类

浅析单例模式与线程安全(Linux环境c++版本)

什么是单例模式 单例模式是设计模式中一种常用模式,定义是Ensure a class has only one instance, and provide a global point of access to it.(确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例) 用<设计模式之禅>里的话说,就是,在一个系统中,要求一个类有且仅有一个对象,如果出现多个就会出现"不良反应",比如以下情景可能会用到单例模式 要求生成唯一序列号的环境 在整个项目中需要一个共享

单例模式简介以及C++版本的实现

    本篇博文主要内容参考 C++的单例模式一文,在此,为原作者耐心细致的分析讲解,表示感谢.本文将结合此篇文章,给出自己做实验后的理解以及代码,作为今天学习的小结.     单例模式,它的意图是保证一个类仅拥有一个实例,并在对外提供一个全局访问点,该实例被所有模块共享.这种模式的应用范围很广,比如系统日志输出,操作系统的窗口管理器,PC连接的键盘等等.     单例模式是一种设计模式,它的具体实现和各种语言特性有关,这里主要介绍在C++上面的实现,测试平台为Win7 64位,VS2010开发

单例模式之懒汉模式Meyers版本

直接看代码: /* 单例模式可以保证:在一个程序当中,一个类有且只有一个实例,并提供一个访问 它的全局访问点 在程序设计当中,很多情况下需要确保一个类只有一个实例 例如: windopws系统中只能有一个窗口管理器 某个程序中只能有一个日志输出系统 一个GUI系统类库中,有且只有一个ImageManager */ #include <iostream> #include <windows.h> #include <process.h> using namespace s

C# 单例模式Lazy&lt;T&gt;实现版本

非Lazy版本的普通单例实现: public sealed class SingletonClass : ISingleton { private SingletonClass () { // the private contructors } public static ISingleton Instance { get { if (instance == null) { lock (InstanceLock) { if (instance != null) { return instance

Java设计模式学习笔记,一:单例模式

开始学习Java的设计模式,因为做了很多年C语言,所以语言基础的学习很快,但是面向过程向面向对象的编程思想的转变还是需要耗费很多的代码量的.所有希望通过设计模式的学习,能更深入的学习. 把学习过程中的笔记,记录下来,只记干货. 第一部分:单例模式的内容 单例模式:类只能有一个实例. 类的特点:1.私有构造器:2.内部构造实例对象:3.对外提供获取唯一实例的public方法. 常见的单例模式实现有五种形式: 1.饿汉式. 2.懒汉式. 3.双重检查锁式. 4.静态内部类式. 5.枚举式. 以下分别

java/android 设计模式学习笔记(一)---单例模式

前段时间公司一些同事在讨论单例模式(我是最渣的一个,都插不上嘴 T__T ),这个模式使用的频率很高,也可能是很多人最熟悉的设计模式,当然单例模式也算是最简单的设计模式之一吧,简单归简单,但是在实际使用的时候也会有一些坑. PS:对技术感兴趣的同鞋加群544645972一起交流 设计模式总目录 java/android 设计模式学习笔记目录 特点 确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 单例模式的使用很广泛,比如:线程池(threadpool).缓存(cache).对

【深入】java 单例模式(转)

[深入]java 单例模式 关于单例模式的文章,其实网上早就已经泛滥了.但一个小小的单例,里面却是有着许多的变化.网上的文章大多也是提到了其中的一个或几个点,很少有比较全面且脉络清晰的文章,于是,我便萌生了写这篇文章的念头.企图把这个单例说透,说深入.但愿我不会做的太差. 首先来看一个典型的实现: 1 /** 2 * 基础的单例模式,Lazy模式,非线程安全 3 * 优点:lazy,初次使用时实例化单例,避免资源浪费 4 * 缺点:1.lazy,如果实例初始化非常耗时,初始使用时,可能造成性能问

单例模式要点回顾

关键代码:构造函数是私有的. 优点: 1.在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存). 2.避免对资源的多重占用(比如写文件操作). 缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化. 单例模式的几种实现方式 单例模式的实现有多种方式,如下所示: 1.懒汉式,线程不安全 是否 Lazy 初始化:是 是否多线程安全:否 实现难度:易 描述:这种方式是最基本的实现方式,这种实现最大的问题就是不支持多