单例模式能够保证一个类只有一个实例, 并提供一个访问该实例的全局节点,所以任何用户在该实例创建之后将不再允许再次创建。
单例模式有多种实现方式 ,当我们要实现的单例模式必须是线程安全,且派生类通过继承就可以得到轻松创建该派生类的单例模式,后续就不必在每个类中都去实现一份单例了。
once_flag 和 call_once 保证创建单例的方法在多线程环境下只会被调用一次
static 关键字 保证 实例只能拥有一份(但需要设计才能保证多线程环境下独一份)
用智能指针管理单例的实例对象
禁用拷贝构造函数和拷贝赋值运算符函数,保证对象不可被拷贝构造和拷贝赋值,但是由于我们这里要设计的这个单例类用以被继承,所以得是 protected。派生类以 public 继承之后,自然会让其成为 private
单例类的构造函数必须是 private,这样才能将类的创建权控制在类的内部,但是由于我们这里要设计的这个单例类用以被继承,所以得是 protected。派生类以 public 继承之后,自然会让其成为 private
单例类的析构函数必须是 private,保证对象不可以在外部随意删除,但是由于我们这里要设计的这个单例类用以被继承,所以得是 protected。派生类以 public 继承之后,自然会让其成为 private
既然希望创建任意类的单例,需要用到模板类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 template <typename T>class Singleton {protected : Singleton () = default ; ~Singleton () = default ; Singleton (const Singleton<T>&) = delete ; Singleton& operator =(const Singleton<T>&) = delete ; static std::shared_ptr<T> instance_; static std::once_flag once_;public : static std::shared_ptr<T> getInstance () { std::call_once (once_, []() { instance_ = std::make_shared <T>(); }); return instance_; } };template <typename T> std::shared_ptr<T> Singleton<T>::instance_ = nullptr ;template <typename T> std::once_flag Singleton<T>::once_;
客户端测试代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 class Student : public Singleton<Student> { friend class Singleton <Student>; public : void doSomething () { std::cout << " Student do" << std::endl; } };void testSingleton () { std::shared_ptr<Student> instance1 = Student::getInstance (); std::shared_ptr<Student> instance2 = Student::getInstance (); if (instance1 == instance2) { std::cout << "Singleton test passed: Both instances are the same." << std::endl; } else { std::cout << "Singleton test failed: Instances are different." << std::endl; } instance1->doSomething (); }int main () { std::thread t1 (testSingleton) ; std::thread t2 (testSingleton) ; t1. join (); t2. join (); return 0 ; }