单例模式:安全
保证一个类仅有一个实例,并提供一个访问它的全局访问点。函数
特色:spa
一、私有的构造函数线程
二、私有的复制构造函数code
三、私有的赋值操做符blog
问题:内存
一、线程安全资源
二、数据的清理get
代码:class
通常有三种写法:
方法一:一个不是线程安全的代码,并且也没有解决内存释放的问题:
1 class Singleton 2 { 3 public: 4 static Singleton* getInstance() 5 { 6 7 /**< 假若有两个线程,第一个线程运行时,判断pInstance是否为空,由于此时pInstance 8 * ==NULL,那么线程将会进入到if结构体内,假设,就在要执行new Singleton这个操做 9 * 时,时间片结束,那么此时pInstance仍是为NULL,此时另外一个线程运行,当它进行判 10 * 断时发现pInstance为空,因此会建立一次,当它执行完后,第一个线程执行,又会产 11 * 生一个新的实例,那么将会产生两个,因此此时是线程不安全的。要想保证安全,必须 12 * if前面加锁 13 */ 14 if(pInstance == NULL) 15 { 16 pInstance = new Singleton; 17 } 18 return pInstance; 19 }; 20 private: 21 Singleton(){}; 22 Singleton(const Singleton &); 23 Singleton& operator=(const Singleton &); 24 25 static Singleton *pInstance; 26 }; 27 28 Singleton* Singleton::pInstance = NULL;
方法二 :只解决了内存释放的问题:
1 class Singleton 2 { 3 public: 4 static Singleton* getInstance() 5 { 6 /**< 其实这里加上互斥操做,就能够实现,便是线程安全,又释放了内存 */ 7 if(pInstance == NULL) 8 { 9 pInstance = new Singleton; 10 } 11 return pInstance; 12 }; 13 14 class Garbage 15 { 16 public: 17 ~Garbage() 18 { 19 if(Singleton::pInstance) 20 { 21 delete pInstance; 22 } 23 }; 24 }; 25 private: 26 Singleton(){}; 27 Singleton(const Singleton &); 28 Singleton& operator=(const Singleton &); 29 30 static Singleton *pInstance; 31 static Garbage m_Garbage; /**< 当这个静态变量释放时,会自动去释放Singleton的资源*/ 32 };
方法三:即解决了线程安全的问题,也解决了内存释放的问题
1 class Singleton 2 { 3 public: 4 static Singleton* getInstance() 5 { 6 /**< 此函数会在全局区中分配空间,并且在整个程序退出时,清理数据 7 * ,因此就不会存在线程不安全的状况 8 */ 9 static Singleton single; 10 return &single; 11 }; 12 private: 13 Singleton(){}; 14 Singleton(const Singleton &); 15 Singleton& operator=(const Singleton &); 16 };