保证一个类仅有一个实例,并提供一个访问它的全局访问点。
让类自身负责保存它的唯一实例。这个类可以保证没有其他实例可以被创建,并且可以提供一个访问该实例的方法。
饿汉版
单例在程序运行时立即执行初始化。由于是在main
函数前初始化,所以没有线程安全问题。
#include <iostream>
#include <memory>
class Singleton {
public:
static Singleton &getInstance() { return instance; }
Singleton(const Singleton &) = delete;
Singleton &operator=(const Singleton &) = delete;
private:
Singleton() = default;
~Singleton() = default;
private:
static Singleton instance;
};
Singleton Singleton::instance;
auto main() -> int {
auto &s = Singleton::getInstance();
}
但是有潜在问题:
由于是 non-local static 对象,在不同编译单元中的初始化顺序是未定义的。即getInstance()
和instance
二者的初始化顺序不确定,如果在实例初始化完成之前调用getInstance()
会返回一个未定义实例。
懒汉版
单例只在第一次被使用时材初始化——延迟初始化。C++11的local static
保证了多线程条件下的初始化行为。但是在之前的版本仍需加锁(double-check那个版本)。
#include <iostream>
#include <memory>
class Singleton {
public:
static Singleton &getInstance() {
static Singleton instance;
return instance;
}
Singleton(const Singleton &) = delete;
Singleton &operator=(const Singleton &) = delete;
private:
Singleton() = default;
~Singleton() = default;
};
auto main() -> int {
auto &s = Singleton::getInstance();
}