单例模式:全局唯一实例,提供一个很容易获取这个实例的接口
线程安全的单例:
懒汉模式(Lazy Loading):第一次获取对象时才创建对象
class Singleton { public: //获取唯一实例的接口函数 static Singleton* GetInstance() { //双重检查,提高效率,避免高并发场景下每次获取实例对象都进行加锁 if (_sInstance == NULL) { std::lock_guard<std::mutex> lock(_mtx); if (_sInstance == NULL) { Singleton* tmp = new Singleton; MemoryBarrier(); //内存栅栏,防止编译器优化 _sInstance = tmp; } } return _sInstance; } static void DelInstance() { if (_sInstance) { delete _sInstance; _sInstance = NULL; } } void Print() { std::cout << _data << std::endl; } private: //构造函数定义为私有,限制只能在类内实例化对象 Singleton() :_data(10) {} //防拷贝 Singleton(const Singleton&); Singleton& operator=(const Singleton&); private: static std::mutex _mtx; //保证线程安全的互斥锁 static Singleton* _sInstance; //指向实例的指针定义为静态私有,这样定义静态成员获取对象实例 int _data; //单例类里面的数据 };
饿汉模式(Eager Loading):第一次获取对象时,对象已经创建好。
简洁、高效、不用加锁,但是在某些场景下会有缺陷。
/*方式一*/ class Singleton { public: static Singleton* GetInstance() { static Singleton sInstance; return &sInstance; } void Print() { std::cout << _data << std::endl; } private: Singleton() :_data(10) {} Singleton(const Singleton&); Singleton& operator=(const Singleton&); private: static Singleton* _sInstance; int _data; }; void TestSingleton() { Singleton::GetInstance()->Print(); }
/*方式二*/ class Singleton { public: static Singleton* GetInstance() { static Singleton sInstance; return &sInstance; } static void DelInstance() { if (_sInstance) { delete _sInstance; _sInstance = NULL; } } void Print() { std::cout << _data << std::endl; } private: Singleton() :_data(10) {} Singleton(const Singleton&); Singleton& operator=(const Singleton&); private: static Singleton* _sInstance; int _data; }; Singleton* Singleton::_sInstance = new Singleton; void TestSingleton() { Singleton::GetInstance()->Print(); Singleton::DelInstance(); }
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。