首页 > 代码库 > 【c++常见问题】-单例模式singleton

【c++常见问题】-单例模式singleton

  通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。

keyword:

  • 创建一个静态的成员变量并且这个成员变量是一个指向当前类的指针。
  • 私有的构造函数可以限制类的创建。包括拷贝构造函数
  • 提供一个静态的公有成员函数访问这个单一的静态类

非线程安全版本

 1 #include <iostream> 2  3 class Singleton { 4 public: 5     //3)提供一个公有的静态成员函数,用以访问这个单一类 6     static Singleton * getSingleton(); 7  8     void setValue(const int val); 9     int getValue() const;10 11 protected:12     int value_;13 14 private:15     //1)创建一个静态的成员变量,该变量指向当前类的指针16     static Singleton *pSingleton;17     //2)私有的构造函数可以限制类的创建18     Singleton();19     Singleton(const Singleton&);20     Singleton& operator=(const Singleton&);21 };22 23 //初始化静态变量24 Singleton* Singleton::pSingleton = NULL;25 26 //初始化成员变量27 Singleton::Singleton():value_(0)28 {29 }30 31 Singleton * Singleton::getSingleton()32 {33     if (NULL == pSingleton) {34         pSingleton = new Singleton();35     }36     return pSingleton;37 }38 39 void Singleton::setValue( const int value)40 {41     value_ = value;42 }43 44 int Singleton::getValue() const45 {46     return value_;47 }48 49 int main(int argc, char const* argv[])50 {51     Singleton * p1 = Singleton::getSingleton();52     p1->setValue(19);53     Singleton * p2 = Singleton::getSingleton();54     std::cout << "value = http://www.mamicode.com/" << p2->getValue() << std::endl;55     return 0;56 }

线程安全版本-c++11

 1  2 Singleton * Singleton::getSingleton() 3 { 4     if (NULL == pSingleton) { 5         std::lock_guard<std::mutex> lock(_mutex); 6         if(NULL == pSingleton) { 7             pSingleton = new Singleton(); 8         } 9     }10     return pSingleton;11 }12

线程安全版本-pthread

 1 #include <iostream> 2 #include <pthread.h> 3  4 class Singleton { 5 public: 6     //3)提供一个公有的静态成员函数,用以访问这个单一类 7     static Singleton * getSingleton(); 8  9     void setValue(const int val);10     int getValue() const;11 12 protected:13     int value_;14 15 private:16     //1)创建一个静态的成员变量,该变量指向当前类的指针17     static Singleton *pSingleton;18     //2)私有的构造函数可以限制类的创建19     Singleton();20     Singleton(const Singleton&);21     Singleton& operator=(const Singleton&);22     static pthread_mutex_t mutex_;23 };24 25 //初始化互斥量26 pthread_mutex_t Singleton::mutex_ = PTHREAD_MUTEX_INITIALIZER;27 28 Singleton * Singleton::getSingleton()29 {30     if (NULL == pSingleton) {31         pthread_mutex_lock(&mutex_);32         if(NULL == pSingleton) {33             pSingleton = new Singleton();34         }35         pthread_mutex_unlock(&mutex_);36     }37     return pSingleton;38 }
1 g++ singleton.cpp -o singleton -lpthread

 

模板版本

 1 #include <iostream> 2 #include <pthread.h> 3 #include <stdlib.h> 4 #include <stdio.h> 5 #include <string.h> 6  7  8 using std::cout; 9 using std::endl;10 11 template<typename T> class Singleton {12 public:13     //3)提供一个公有的静态成员函数,用以访问这个单一类14     static T & getInstance();15 16 private:17     //1)创建一个静态的成员变量,该变量指向唯一对象的指针18     static T * volatile pInstance_;19     //2)私有的构造函数可以限制对象的创建20     Singleton();21     Singleton(const Singleton&);22     Singleton& operator=(const Singleton&);23     static pthread_mutex_t mutex_;24 };25 26 //初始化静态变量27 template<typename T>28 T * volatile Singleton<T>::pInstance_ = NULL;29 30 //初始化互斥量31 template<typename T>32 pthread_mutex_t Singleton<T>::mutex_ = PTHREAD_MUTEX_INITIALIZER;33 34 template<typename T>35 T & Singleton<T>::getInstance()36 {37     //double-check lock38     if (NULL == pInstance_) {39         pthread_mutex_lock(&mutex_);40         if(NULL == pInstance_) {41             pInstance_ = new T;42         }43         pthread_mutex_unlock(&mutex_);44     }45     return *pInstance_;46 }47 48 class ApplicationImpl49 {50 public:51     ApplicationImpl(){52         cout << "ApplicationImpl()" << endl;53     }54 55     ~ApplicationImpl(){56         cout << "~ApplicationImpl()" << endl;57     }58 59     void run(){60         cout << "run()" << endl;61     }62 };63 64 typedef Singleton<ApplicationImpl> Application;65 66 void *routine(void *arg){67     Application::getInstance().run();68 }69 70 int main(int argc, char const* argv[])71 {72 73     Application::getInstance().run();74 75     pthread_t tid;76     int ret;77     ret = pthread_create(&tid, NULL, routine, NULL);78     if( ret != 0 )79     {80         fprintf(stderr, "pthread create:%s\n", strerror(ret));81         exit(EXIT_FAILURE);82     }83 84     Application::getInstance().run();85 86     pthread_join(tid,NULL);87 88     return 0;89 }

 

【c++常见问题】-单例模式singleton