单例模式
本例适用于单线程!需要线程安全的例子(互斥)可看这里,写的很好。。。我网上看到new/delete/malloc是线程安全的,只要调用了多线程函数,链接的库就是支持线程安全的,看这里 ,但这并不意味着我们就不需要加锁了,因为在判断m_pLogger==0时,很有可能两个线程都同时判断为该条件true了,这和volatile没关系!知乎上这个回答挺好
#include <iostream> using namespace std; //xxx.h class CLogger { public: friend CLogger* GetLogger(); void info(const char* s) const { cout << s << endl; } private: CLogger() { //初始化工作 } ~CLogger() { cout << "~CLogger()" << endl; } CLogger(const CLogger&); CLogger& operator =(const CLogger&); static CLogger* GetInstance() { if(m_pLogger == NULL) { //lock here if (m_pLogger == NULL) m_pLogger = new CLogger; //unlock here } return m_pLogger; } static CLogger * volatile m_pLogger; class CGarBo { public: ~CGarBo() { cout << "~GarBo()" << endl; if(m_pLogger) { delete ::m_pLogger; m_pLogger = NULL; } } }; static CGarBo m_garbo; }; //xxx.cpp CLogger * CLogger::m_pLogger = NULL; CLogger::CGarBo CLogger::m_garbo;//不含这句,编译虽不会出错,但不会生成m_garbo实例! CLogger* GetLogger() { return CLogger::GetInstance(); } //test.cpp int main() { GetLogger()->info("hello world"); return 0; }
也可以这样:
CLogger* GetLogger() { static CLogger s_logger; return &s_logger; } /* 初次调用该函数时,局部静态变量才初始化。而非是程序运行时(main前)就初始化。这和全局与class static变量不同~ 析构是在程序结束(main后)时,而不是该函数结束时。可通过以下测试: Sleep(4000); GetLogger(); Sleep(4000) */
如此,不在需要new/delete,也不需要嵌套类和加锁了,两个static成员变量也不需要了。