C++实现设计模式之--单例模式
来源:互联网 发布:手板编程招聘 编辑:程序博客网 时间:2024/06/04 19:48
C++实现设计模式之–单例模式
在程序中,会经常使用new来创建对象,特别是在后期,程序越来越复杂,那么对对象的管理就特别的复杂,所有对在程序运行过程中只需要一个对象,并对其进行操作的类,继承单例模式,从而方便管理。例如网络游戏运行中,只需要创建一个网络的对象,来实现数据的发送,或者是游戏中全局管理对象。很形象的例子就是,一部电影,总导演只有一个,不可能有很多个导演,导演来控制整部电影改怎么拍。
单例的实现方式有很多种,最简单的一种实现方式如下:
方式一
class Singleton{public: static Singleton* getInstance() { if (nullptr== _instance ) { _instance = new Singleton(); } return _instance; }private: static Singleton* _instance;};
当然在实际开发中,不可能为每一个类写一个单例方法,所以可以设计成模板,让需要实现单例的类继承该模板,模板实现如下:
template<typename T>class ApplicationSingleTon{public: static T* getInstance() { if (_instance == nullptr) { _instance = new T(); } return _instance; }private: static T* _instance;}template <typename T>T* ApplicationSingleTon<T>::_instance = nullptr;
在需要实现单例的类继承该模板, 如
#define Director_Ins Director::getInstance();class Director : public ApplicationSingleTon<Director>{public: void display() { std::cout<<"singleton director!"; };};
为了方便,直接定义了宏,在需要调用该对象的地方,直接调用Director_Ins 便可以。这种单例的实现,相对简单,缺点是在多线程的情况下,可能会创建多个Singleton实例。比如这么一种情况,线程A和线程B同事达到if NUll这里,A,B都判断为NULL,所以都执行了new操作,这是就创建了两个对象。所以这个时候就出现个了另外一种实现方式。
方式二
std::mutex m;class Singleton{public: static Singleton* getInstance() { if (_instance == NULL) { if (_instance == NULL) { m.lock(); _instance = new Singleton(); } m.unlock(); } return _instance; }private: static Singleton* _instance;};Singleton* Singleton::_instance = NULL;
通过增加一个互斥锁,来避免多线程访问时重新创建对象的问题。细心的你可能会发现,这个版本的getinstance中,对_instance进行两次是否为NULL的判断,为什么要这样做呢。利用双检锁,利用两次判断,减少了加锁/解锁的操作,主要保证了线程的安全。这种方式就很有效的解决了上面那种方式所带了的问题,在这种方式下,再遇到上面那种情况,当同时到达判断为null,然后会加锁,此时在判断一次是否为null,用来确定该对象还未创建,确保了全程只有一个对象被创建。这种方式的缺点是当对大数据进行操作的时候,就会出现性能瓶颈,于是又有第三种方式:
方式三
class Singleton{public: static Singleton* getInstance() { return const_cast<Singleton*>(_instance); }private: static const Singleton* _instance; };const Singleton* Singleton::_instance = new Singleton();
这种方式将对象的初始化放在了静态初始化阶段,这样,在运行mian函数之前就已经将该对象初始化,不再需要在运行过程中创建。但是这样一来就出现了另外一个问题,对象的销毁,因为静态成员的生命周期是程序运行期间,知道程序运行结束,所以这种方式只适用于在整个程序运行期间一直存在的对象。
介绍了这么多单例模式实现的方式,都主要是对象的创建,但是对象有创建,就必定会有销毁,这时你可能会问了,都设计成单例类了,肯定是整个程序运行的过程中会一直需要的啊。说的对,但是有这样的特殊情况,如连接数据库的类,肯定要在程序结束前释放对象。
参考了果冻想的博客,借鉴他的实现方式:
class Singleton{public: static Singleton* getInstance() { return _instance; }private: static Singleton* _instance; class Release { public: ~Release() { if (_instance != NULL) { delete _instance; _instance = NULL; } } }; static Release rl;};Singleton* Singleton::_instance = new Singleton();Singleton::Release Singleton::rl;
在此感谢果冻想博客给与的思路与见解。
果冻想C++设计模式——单例模式: http://www.jellythink.com/archives/82
- 设计模式--单例模式 C++实现
- (C#)设计模式 之 单例模式
- 设计模式之单例模式(C++)
- C#--设计模式之单例模式
- objective-C之宏定义实现单例设计模式
- Objective-c 实现单例设计模式
- Objective-C 设计模式之单例
- Objective-C之单例设计模式
- scala实现设计模式之单例设计模式
- 设计模式之-单例实现
- 设计模式之单例模式(c++)实现及问题
- 使用Object-C实现23种设计模式之单例模式
- 设计模式之单例模式(C++)
- C语言和设计模式(之单例模式)
- Objective-C中的设计模式之单例模式
- 【C++】单例模式之C++实现
- 设计模式之—单例模式(Singleton)-Java实现
- 设计模式之单例模式(python实现)
- 华硕a501lb5200加内存和固盘并装上win7系统并设置固盘为第一启动
- Android动画的使用点滴
- 使用ssh公钥实现免密码登录
- VS2012配置OpenGL
- Coursera机器学习 week3 逻辑回归 编程作业代码
- C++实现设计模式之--单例模式
- linux下创建和删除软、硬链接
- margin重叠现象探讨研究
- BZOJ4439——[Swerc2015]Landscaping
- Mybatis中运用小技巧(二) like的使用
- javascript正则RegExp.test()需要注意:不具有可重入性
- 欢迎使用CSDN-markdown编辑器备份
- 带头双向循环链表的插入和删除
- Socket简单实例(简单实现调用accpet()方法开始监听)