设计模式--单例模式: 创建一个安全并且高效的Sington很重要。 (1)单例类保证全局只有一个唯一实例对象; (2)单例类提供获取这个唯一实例的接口。 下面为四种创建单例类的方法: //单例模式 ////////不考虑线程安全的单例类////////// class Singleton { public: //获取唯一对象实例的接口函数 static Singleton * GetIntance() { if (_sIntance == NULL ) { if (_sIntance == NULL ) { _sIntance = new Singleton (); } } return _sIntance; } //删除实例对象 static void DelIntance() { if (_sIntance) { delete _sIntance; _sIntance = NULL; } } void Print() { cout << _data << endl; } private: //构造函数定义为私有,限制只能在类内创建对象 Singleton() :_data(0) {} //防拷贝 Singleton( const Singleton &); Singleton& operator=(const Singleton&); private: static Singleton * _sIntance;//指向实例的指针定义为静态私有,定义静态函数获取实例对象 int _data;//单例类里的数据 }; Singleton* Singleton ::_sIntance = NULL; //静态成员只能在类外初始化 void TestSingleton() { Singleton::GetIntance()->Print(); Singleton::DelIntance(); }
////////////线程安全的单例模式(懒汉模式)//////////// class Singleton { public: //获取唯一对象实例的接口函数 static Singleton * GetIntance() { //使用双重检查,提高效率,避免高并发场景下每次获得实例对象都进行加锁,浪费资源 if (_sIntance == NULL ) { std:: lock_guard<std::mutex > lck(_mtx); if (_sIntance == NULL ) { Singleton* tmp = new Singleton(); MemoryBarrier(); //内存栅栏,防止编译器重排栅栏后的赋值到栅栏之前 _sIntance = tmp; } } return _sIntance; } //删除实例对象 static void DelIntance() { std:: lock_guard<std::mutex > lck(_mtx); if (_sIntance) { delete _sIntance; _sIntance = NULL; } } void Print() { cout << _data << endl; } private: //构造函数定义为私有,限制只能在类内创建对象 Singleton() :_data(0) {} //防拷贝 Singleton( const Singleton &); Singleton& operator=(const Singleton&); private: static mutex _mtx;//保证线程安全的互斥锁 static Singleton * _sIntance;//指向实例的指针定义为静态私有,定义静态函数获取实例对象 int _data;//单例类里的数据 }; Singleton* Singleton ::_sIntance = NULL; //静态成员只能在类外初始化 mutex Singleton::_mtx; void TestSingleton() { Singleton::GetIntance()->Print(); Singleton::DelIntance(); }
/////////////饿汉模式(简洁,不加锁)///////////////////////// class Singleton { public: //获取唯一对象实例的接口函数 static Singleton * GetIntance() { static Singleton sIntance; return &sIntance; } void Print() { cout << _data << endl; } private: //构造函数定义为私有,限制只能在类内创建对象 Singleton() :_data(0) {} //防拷贝 Singleton( const Singleton &); Singleton& operator=(const Singleton&); private: int _data;//单例类里的数据 }; void TestSingleton() { Singleton::GetIntance()->Print(); } ////////// /////饿汉模式2//////////////////// class Singleton { public: //获取唯一对象实例的接口函数 static Singleton *GetIntance() { assert(_sIntance); return _sIntance; } //删除实例对象 static void DelIntance() { if (_sIntance) { delete _sIntance; _sIntance = NULL; } } void Print() { cout << _data << endl; } private: //构造函数定义为私有,限制只能在类内创建对象 Singleton() :_data(0) {} //防拷贝 Singleton( const Singleton &); Singleton& operator=(const Singleton&); private: static Singleton * _sIntance;//指向实例的指针定义为静态私有,定义静态函数获取实例对象 int _data;//单例类里的数据 }; Singleton* Singleton ::_sIntance = new Singleton; //静态成员只能在类外初始化 void TestSingleton() { Singleton::GetIntance()->Print(); Singleton::DelIntance(); }
///////////////使用RAII GC自动回收实例对象的方式/////////// class Singleton { public: //获取唯一对象实例的接口函数 static Singleton * GetIntance() { assert(_sIntance); return _sIntance; } //删除实例对象 static void DelIntance() { if (_sIntance) { delete _sIntance; _sIntance = NULL; } } void Print() { cout << _data << endl; } class GC { public: ~GC() { cout << "DelIntance" << endl; DelIntance(); } }; private: //构造函数定义为私有,限制只能在类内创建对象 Singleton() :_data(0) {} //防拷贝 Singleton( const Singleton &); Singleton& operator=(const Singleton&); private: static Singleton * _sIntance;//指向实例的指针定义为静态私有,定义静态函数获取实例对象 int _data;//单例类里的数据 }; Singleton* Singleton ::_sIntance = new Singleton; //静态成员只能在类外初始化 //使用RAII,定义全局的GC对象释放对象实例 Singleton::GC gc; void TestSingleton() { Singleton::GetIntance()->Print(); }