Skip to content

Instantly share code, notes, and snippets.

@ZJUGuoShuai
Last active August 19, 2023 04:03
Show Gist options
  • Save ZJUGuoShuai/ffda62265f2ff44073ade8aad98b5ba3 to your computer and use it in GitHub Desktop.
Save ZJUGuoShuai/ffda62265f2ff44073ade8aad98b5ba3 to your computer and use it in GitHub Desktop.
C++ 如何实现线程安全的单例模式

基本版本

class Singleton {
  Singleton() = default;

 public:
  Singleton(const Singleton&)            = delete;
  Singleton& operator=(const Singleton&) = delete;

  static Singleton& getInstance() {
    static Singleton instance;
    return instance;
  }
};

说明:

  • 拷贝构造和拷贝赋值都被设置为了 delete,因为单例对象不允许被拷贝,只允许被移动
  • 默认构造函数必须要有,否则无法创建实例。但这个接口也不能对外接提供,因为单例只能通过 static 方法 getInstance() 创建,因此将默认构造函数设为私有方法。
  • C++11 标准保证了「即使有多个线程同时执行 getInstance() 方法,也只有一个线程执行 instance 对象的构造」。 因此只要编译器实现了 C++11 标准,就能保证线程安全

CRTP 基类

如果你的项目中需要实现多种单例 class,你可以先实现一种单例基类,然后继承这个基类,派生类也将成为单例类。

template <typename T>
class SingletonBase {
 protected:
  SingletonBase() = default;

 public:
  SingletonBase(const SingletonBase&)            = delete;
  SingletonBase& operator=(const SingletonBase&) = delete;

  static T& getInstance() {
    static T instance;
    return instance;
  }
};

class SingletonA : public SingletonBase<SingletonA> {
  SingletonA() = default;
  friend class SingletonBase<SingletonA>;

 public:
  void doSomething() {
    // do something
  }
};

参考

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment