单例模式总结

154 阅读1分钟

懒汉式指针实现(用到时再初始化):

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…