【C++】实现Singleton模式
2017-07-29 17:37
260 查看
单例模式,就是设计一个类,我们只能生成该类的一个实例。
而单例模式的实现方式有两种:懒汉模式和饿汉模式
实现1、教科书
构造函数声明为private或protect防止被外部函数实例化,内部保存一个private static的类指针保存唯一的实例,实例的动作由一个public的类方法代劳,该方法也返回单例类唯一的实例。
这是一个很棒的实现,简单易懂。但这是一个完美的实现吗?不!该方法是线程不安全的,考虑两个线程同时首次调用instance方法且同时检测到p是NULL值,则两个线程会同时构造一个实例给p,这是严重的错误!同时,这也不是单例的唯一实现!
线程安全的懒汉模式
(1)加锁的经典懒汉实现
(2)内部静态变量的懒汉实现
注:饿汉模式本身就是线程安全的。
在访问量较小时,采用懒汉实现。这是以时间换空间。
单利模式的释放
类CGarbo被定义为CSingleton的私有内嵌类,以防该类被在其它地方滥用。
在程序运行结束时,系统会调用CSingleton的静态成员Garbo的析构函数,该析构函数会删除单例的唯一实例。
使用这种方法释放C++单例模式对象有以下特征:
在单例类内部定义专有的嵌套类。
在单例类内定义私有的专门用于释放的静态成员。
利用程序在结束时析构全局变量的特性,选择最终的释放时机。
使用C++单例模式的代码不需要任何操作,不必关心对象的释放。
而单例模式的实现方式有两种:懒汉模式和饿汉模式
懒汉模式
懒汉式是典型的时间换空间,也就是每次获取实例都会进行判断,看是否需要创建实例,浪费判断的时间。当然,如果一直没有人使用的话,那就不会创建实例,则节约内存空间。实现1、教科书
构造函数声明为private或protect防止被外部函数实例化,内部保存一个private static的类指针保存唯一的实例,实例的动作由一个public的类方法代劳,该方法也返回单例类唯一的实例。
class Singleton { private: Singleton() //私有构造函数 {} static Singleton* _instance; public: static Singleton* getInstace();//静态成员方法获取实例 }; Singleton* Singleton::_instance = NULL; Singleton* Singleton::getInstace() { if (_instance == NULL) _instance = new Singleton(); return _instance; }
这是一个很棒的实现,简单易懂。但这是一个完美的实现吗?不!该方法是线程不安全的,考虑两个线程同时首次调用instance方法且同时检测到p是NULL值,则两个线程会同时构造一个实例给p,这是严重的错误!同时,这也不是单例的唯一实现!
线程安全的懒汉模式
(1)加锁的经典懒汉实现
class Singleton1 { protected: Singleton1() { pthread_mutex_init(&mutex); } private: static Singleton1* p; public: static pthread_mutex_t mutex; static Singleton1* initance(); }; pthread_mutex_t Singleton1::mutex; Singleton1* Singleton1::p = NULL; Singleton1* Singleton1::initance() { if (p == NULL) { pthread_mutex_lock(&mutex); if (p == NULL) p = new Singleton1(); pthread_mutex_unlock(&mutex); } return p; }
(2)内部静态变量的懒汉实现
class Singleton3 { protected: Singleton3() { pthread_mutex_init(&mutex); } public: static pthread_mutex_t mutex; static Singleton3* initance(); }; pthread_mutex_t Singleton3::mutex; Singleton3* Singleton3::initance() { pthread_mutex_lock(&mutex); static Singleton3 obj; pthread_mutex_unlock(&mutex); return &obj; }
饿汉模式
饿汉式是典型的空间换时间,当类装载的时候就会创建类实例,不管你用不用,先创建出来,然后每次调用的时候,就不需要再判断了,节省了运行时间。注:饿汉模式本身就是线程安全的。
class singleton { protected: singleton() {} private: static singleton* p; public: static singleton* initance(); }; singleton* singleton::p = new singleton; singleton* singleton::initance() { return p; }
两种模式的区别
由于要进行线程同步,所以在访问量比较大,或者可能访问的线程比较多时,采用饿汉实现,可以实现更好的性能。这是以空间换时间。在访问量较小时,采用懒汉实现。这是以时间换空间。
单利模式的释放
class CSingleton: { // 其它成员 public: static CSingleton * GetInstance() private: CSingleton(){}; static CSingleton * m_pInstance; class CGarbo // 它的唯一工作就是在析构函数中删除CSingleton的实例 { public: ~CGarbo() { if (CSingleton::m_pInstance) delete CSingleton::m_pInstance; } }; static CGarbo Garbo; // 定义一个静态成员,在程序结束时,系统会调用它的析构函数 };
类CGarbo被定义为CSingleton的私有内嵌类,以防该类被在其它地方滥用。
在程序运行结束时,系统会调用CSingleton的静态成员Garbo的析构函数,该析构函数会删除单例的唯一实例。
使用这种方法释放C++单例模式对象有以下特征:
在单例类内部定义专有的嵌套类。
在单例类内定义私有的专门用于释放的静态成员。
利用程序在结束时析构全局变量的特性,选择最终的释放时机。
使用C++单例模式的代码不需要任何操作,不必关心对象的释放。
相关文章推荐
- CSDN技术中心 Singleton模式的C++实现研究(转载)
- C++完美实现Singleton模式
- C++完美实现Singleton模式
- C++完美实现Singleton模式
- C++实现Singleton模式
- 设计模式C++实现--Singleton模式
- 设计模式的解析和实现(C++)之五-Singleton模式
- 常见设计模式的解析和实现(C++)之五-Singleton模式
- C++完美实现Singleton模式
- C++完美实现Singleton模式
- C++完美实现Singleton模式zz
- C++实现Singleton模式
- C++实现Creational - Singleton模式
- 【设计模式】Singleton模式C++实现
- Singleton模式C++实现
- C++实现Creational - Singleton模式
- C++完美实现Singleton模式
- C++完美实现Singleton模式
- C++完美实现Singleton模式
- C++的Singleton模式实现