单例是经常用到的一种设计模式,看似简单实则要考虑很多方面,如线程安全、懒加载性能等,本文提供C++单例的两种实现,具有较高的适用性。
局部静态变量实现
class Singleton
{
public:
static Singleton& instance();
protected: //访问修饰符声明为protected是为了继承;如不被继承声明为private
Singleton() = default;
~Singleton() = default;
private:
/*
拷贝和赋值构造函数声明为delete时,访问修饰符声明为public、protected、private均可
Singleton(const Singleton&) = delete;
Singletone& operator=(const Singleton&) = delete;
*/
Singleton(const Singleton&);
Singleton& operator=(const Singleton&);
};
Singleton& Singleton::instance()
{
static Singleton _s_instance;
return _s_instance;
}
说明:
- 线程安全问题,C++11后静态变量初始化保证线程安全。但是要注意以下问题,C++11依赖TLS(线程本地存储)实现静态局部变量的线程安全初始化,Windows Vista及以后版本系统支持, Windows XP, Windows Server 2003不支持,因此XP等系统不能使用此单例模式的实现。详情参见
使用call_once实现
#include <memory>
#include <mutex>
class Singleton
{
public:
static std::shared_ptr<Singleton> instance();
//智能指针的析构函数释放资源时,需要能访问到Singleton的析构函数,因此次实现声明为public
//其他单例实现方式时,析构函数声明为public或者private均可
~Singleton() = default;
private:
Singleton() = default;
Singleton(const Singleton&);
Singleton& operator=(const Singleton&);
private:
static std::shared_ptr<Singleton> _s_instance;
static std::once_flag _s_once_flag;
};
std::shared_ptr<Singleton> Singleton::_s_instance = nullptr;
std::once_flag Singleton::_s_once_flag;
std::shared_ptr<Singleton> Singleton::instance()
{
std::call_once(_s_once_flag, [&]()
{
_s_instance.reset(new Singleton());
});
return _s_instance;
}
说明:
- 该单例利用std::call_once和std::once_flag实现,std::call_once的调用是线程安全的,且为懒加载方式,详情参见