参考文献:
(1) WiKi:https://zh.wikipedia.org/wiki/%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F
(2) 简单单例模式理解:https://blog.csdn.net/liang19890820/article/details/61615495
(3) 几种单例模式设计的优缺点:https://blog.csdn.net/Jack__Frost/article/details/66475741
(4) 优缺点详情:https://blog.csdn.net/cselmu9/article/details/51366946
//设计模式之单例模式:目的是使得类的一个对象在系统中只有唯一实例 #include <iostream> template<typename _TYPE_> class Singleton { public: static _TYPE_* instance() { static _TYPE_ obj; return &obj; //避免默认的拷贝构造 } protected: //CFile 可以构造和析构 Singleton() {} ~Singleton() {} private: Singleton(const Singleton &) {} //避免默认的拷贝构造 Singleton& operator = (const Singleton &) {} }; class CFile : public Singleton<CFile> { public: void Init() { std::cout << "init " << ++m_num << std::endl; } protected: CFile() { m_num = 0; std::cout << m_num << std::endl; } ~CFile() { m_num = 0; } friend Singleton<CFile>; //如果构造为protected时,Singleton类中的instance函数要范围构造,则需为友元 private: int m_num; }; int main() { Singleton<CFile>::instance()->Init(); Singleton<CFile>::instance()->Init(); CFile *cfile_1 = Singleton<CFile>::instance(); cfile_1->Init(); //CFile *cfile_2 = new CFile(); //cfile_2->Init(); //cfile_2->instance()->Init(); //delete cfile_2; CFile::instance()->Init(); //推荐用法 CFile *cfile_3 = CFile::instance(); cfile_3->Init(); getchar(); return 0; }
Boost中也有单例模式的可继承实现,以下是类似例子,非单纯的单例模式:
#include <boost/noncopyable.hpp> #include <boost/serialization/singleton.hpp> #include <iostream> // 使用方式1:模板参数方式 class CTest :public boost::noncopyable // 不能复制、赋值 { public: void Set(int i) { m_val = i; } void Print() const { std::cout << m_val << std::endl; } private: int m_val; }; // 使用typedef以及宏来简化使用 typedef boost::serialization::singleton<CTest> singleton_ctest; // 使用模板的方式只允许单个实例 #define sCTest singleton_ctest::get_mutable_instance() // 非const实例 #define sCTest_const singleton_ctest::get_const_instance() // const实例 // 使用方式2:继承方式 class CDerived :public boost::serialization::singleton<CDerived> // 只允许单个实例,不能复制、赋值(基类派生自boost::noncopyable) { public: void Set(int i) { m_val = i; } void Print() const { std::cout << m_val << std::endl; } private: int m_val; }; #define sCDerived CDerived::get_mutable_instance() // 非const实例 #define sCDerived_const CDerived::get_const_instance() // const实例 int main(void) { // singleton_ctest obj1; // singleton_ctest obj2; sCTest.Set(10); sCTest_const.Print(); // 10 // 操作类的非static成员 CDerived cobj; CDerived cobj2; cobj2.Set(89); cobj.Set(10); // 单例的概念:并非是不能定义两个类对象本身 // 而是当有多个对象时,通过boost提供的静态成员函数get_mutable_instance()返回实例再调用普通成员函数之后, // 类对象的结果保持一致,就好像类中的所有数据成员都是static一样 // 这时的类好像定义了两种同名的数据成员以及成员函数:static与非static // 非static由普通方式调用:即先定义类对象,再调用成员函数 // static先调用由boost提供的get_mutable_instance()(或get_const_instance())再调用成员函数的方式 // 从而保证单例(因为类的所有成员共享static) // 两种调用互不影响(各自数据成员是分离的),唯一的影响是类现在派生自boost::noncopyable //操作类的“static成员” CDerived::get_mutable_instance().Set(20); CDerived::get_mutable_instance().Print(); // 20 // same way: sCDerived.Set(20); sCDerived.Print(); // 20 //sCDerived_const.Set(89); // error sCDerived_const.Print(); // 20 cobj2.get_mutable_instance().Print(); // 20 cobj.get_mutable_instance().Print(); // 20 // 操作类的非static成员 cobj2.Print(); // 89 cobj.Print(); // 10 // 实际使用中,我们没有必要也不应该直接定义类对象,而是应该总是通过使用类的static成员函数: // classname::get_mutable_instance().memberFunction(para);(或get_const_instance())来确保“单个实例” // 本例中定义的宏的使用方式与类对象的使用方式相同:name.member_function(para); // 可以将宏当做“对象” getchar(); return 0; }