懒汉式指针实现(用到时再初始化):
class Singleton
{
private:
Singleton() {};
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
static Singleton* instance_;
static mutex m_;
public:
static Singleton* GetInstance();
};
// 下面这两句不可少,不然会报连接错误,因为类里面只是声明,需要这里的定义
Singleton* Singleton::instance_ = NULL;
mutex Singleton::m_;
Singleton* Singleton::GetInstance()
{
// 需要double check
// 之所以需要double check,因为如果有线程A执行完第一个 if (instance_ == nullptr) 之后,切换到
// 线程B执行,然后线程B检测到instance_位nullptr,会创建一个对象,然后再切换回线程A,因为A已经判断
// 为nullptr,会继续创建对象,因此导致创建两份对象
if (instance_ == nullptr) {
m_.lock();
if (instance_ == nullptr) {
instance_ = new Singleton();
}
m_.unlock();
}
return instance_;
}
饿汉式(一开始就初始化,不用等到用时)
class Singleton
{
protected:
Singleton(){}
private:
static Singleton* p;
public:
static Singleton* initance();
};
Singleton* Singleton::p = new Singleton;
Singleton* singleton::initance()
{
return p;
}
局部静态变量方式:
class Singleton
{
private:
// 默认构造函数、拷贝构造函数、赋值操作符均为 私有,且后两个只声明不实现,防止产生其他对象
Singleton() {};
Singleton(const Singleton& rhs);
Singleton& operator=(const Singleton& rhs);
public:
static Singleton& GetInstance()
{
// c++ 11 通过内部加锁的方式保证局部静态对象的线程安全,c++0x之前的编译器不做保证
static Singleton single;
return single;
}
};
参考:
www.aristeia.com/Papers/DDJ_…
www.cnblogs.com/william-che…
wuchong.me/blog/2014/0…