C++实现单例模式
来源:互联网 发布:如何做好网络咨询 编辑:程序博客网 时间:2024/06/06 15:40
C++实现单例模式
第一次写关于技术的文章,选择了一个单例模式这样的例子作为开头。用自己的理解去实现,希望能够表达清楚。
懒汉式
class Singleton{ private: Singleton(){} static Singleton* instance; public: static Singleton* getInstance() { if(NULL == instance) { instance = new Singleton(); } return instance; }};
//静态成员变量必须在实现文件中进行定义,而不仅仅是在头文件中声明
Singleton* Singleton::instance = NULL;
这个代码简单,但是会存在内存泄漏的问题,new出来的对象始终没有释放,下面是它的一种改进。
class Singleton{ private: Singleton() {} static Singleton* m_pInstance; //嵌套类 class CGrabo { public: ~CGrabo() { if(Singleton::m_pInstance) { delete Singleton::m_pInstance; Singleton::m_pInstance = NULL; } } }; static CGrabo Grabo; public: static Singleton* getInstance() { if(NULL == m_pInstance) { m_pInstance = new Singleton(); } return m_pInstance; }};
说明:在程序运行结束的时候,静态成员变量Grabo的析构函数会被调用,该析构函数会删除单例中的唯一实例。其特点是在单例类的内部定义专有的内部类,并且定义该类的一个私有静态成员,利用静态变量的特性,选择最终的释放时机。
饿汉式
class Singleton{ private: Singleton() {} public: static Singleton * getInstance() { static Singleton instance; return &instance; }};
饿汉模式实现简单并且是线程安全的,在类创建的同事就已经创建好一个静态的对象供系统使用。
懒汉模式在多线程中会出现线程安全的问题,因为在懒汉模式中单例实例有两种状态,分别是初始化和未初始化。假设单例实例还没有初始化,有两个线程同事调用getInstance方法,这是执行m_pInstance==NULL肯定为真,然后两个线程都初始化一个实例,最后得到的指针并不是指向同一个地方,不满足单例的定义了。在多线程环境下,要对其进行修改。
多线程下的单例模式
——————————— 懒汉模式
class Singleton{ private: static Singleton* m_pInstance; Singleton(){} //嵌套类 class CGrabo { public: ~CGrabo() { if(Singleton::m_pInstance) { delete Singleton::m_pInstance; Singleton::m_pInstance = NULL; } } }; static CGrabo Grabo; public: static Singleton* getInstance();};
在实现类实现
Singleton* Singleton::getInstance(){ if(NULL == m_pInstance) { Lock();//通过同步类来实现,如临界区,事件,互斥,信号量等 if(NULL == m_pInstance) { m_pInstance = new Singleton(); } UnLock(); } return m_pInstance;}
这里为什么需要两次判断m_pInstance??这是为了防止一个线程进入临界区创建实例,另外的线程也进入临界区创建实例,所以加上第二个判断if(NULL==m_pInstance),确保不会重复创建。
如果是这样写是否也可以???
Singleton* Singleton::getInstance(){ lock(); if(NULL == m_pInstance) { m_pInstance = new Singleton(); } unlock(); return m_pInstance;}
这样写的话,会稍微影响性能,因为每次判断是否为空都需要被锁定,如果有很多线程的话,就会造成大量线程阻塞。
既然如此,也会有人想能不能把同步锁放入到判断空里面,这样就不会每次都锁了,像这样:
Singleton* Singleton::getInstance(){ if(NULL == m_pInstance) { lock(); m_pInstance = new Singleton(); unlock(); } return m_pInstance;}
这样就又回到了饿汉模式的非线程安全上去了。
这是总结的一些东西,或许并不是总结得很好,也会有很多自己没有想到的东西,或者还有更加巧妙的方法来改进,这里暂时就不再深究了。
- 设计模式--单例模式 C++实现
- Objective C 中实现单例模式
- Objective C 实现Singleton(单例)模式.
- Objective-C实现单例模式
- 【Objective-C】单例模式的实现
- objective-C 实现单例模式
- 单例模式代码实现(C++)
- 单例模式 (C语言实现)
- Objective-C实现单例模式
- Objective-C单例模式实现
- Objective-C 单例模式的实现
- Objective-c 实现单例设计模式
- c++--Singleton单例模式的实现
- 单例模式,C/C++实现
- 【C++】单例模式之C++实现
- C#单例模式
- C#-单例模式
- 单例模式(C++)
- 计算机图形学(三)_图元的属性_16_ 反走样_1_产生的原因
- maven 下载慢,maven 国内镜像
- 手机抓取软件合法吗
- 腾讯云的Ubuntu LEMP环境配置
- 经典算法题:大数据处理常见算法题
- C++实现单例模式
- 四元数
- MySQL之MySQL常用的函数方法
- Dokuwiki如何添加edittable插件
- Sencha Touch快速入门2.0之Sencha Touch App开发
- 初学spring的方法(1)
- Android图片下载缓存库picasso解析
- Android 不同手势的识别:滑动、放大缩小
- 网络编程基础---------陈Hong鑫