单例模式

  

1. 什么是单例模式

单例模式(Singleton Pattern,也称为单件模式),使用最广泛的设计模式之一。其意图是保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。

定义一个单例类:

  1. 私有化它的构造函数,以防止外界创建单例类的对象;
  2. 使用类的私有静态指针变量指向类的唯一实例;
  3. 使用一个公有的静态方法获取该实例。

2.懒汉版

static Singleton* getInstance() {
	if(instance == NULL) {
		Lock lock;  // 基于作用域的加锁,超出作用域,自动调用析构函数解锁
        if(instance == NULL) {
        	instance = new Singleton();
        }
	}
	return instance;
}

  

instance = new Singleton()可以分为3步:
1.分配一块空间
2.调用构造器构造对象
3.这块空间赋值给instance
意外情况:
正常的123执行顺序变成了132,线程执行到13时时间片结束,挂起,下一次另一个线程执行到
if(instance == NULL) 
此时不为空,返回instace,但是这个instance还没有构造出来,导致出错。

C++11中的atomic类的默认memory_order_seq_cst保证了3、6行代码的正确同步
atomic<Widget*> Widget::pInstance{ nullptr };
Widget* Widget::Instance() {
    if (pInstance == nullptr) { 
        lock_guard<mutex> lock{ mutW }; 
        if (pInstance == nullptr) { 
            pInstance = new Widget(); 
        }
    } 
    return pInstance;
}

  

Best of All:

C++11规定了local static在多线程条件下的初始化行为,要求编译器保证了内部静态变量的线程安全性。在C++11标准下,《Effective C++》提出了一种更优雅的单例模式实现,使用函数内的 local static 对象。这样,只有当第一次访问getInstance()方法时才创建实例。这种方法也被称为Meyers' Singleton。C++0x之后该实现是线程安全的,C++0x之前仍需加锁。

// version 1.2
class Singleton
{
private:
	Singleton() { };
	~Singleton() { };
	Singleton(const Singleton&);
	Singleton& operator=(const Singleton&);
public:
	static Singleton& getInstance() 
        {
		static Singleton instance;
		return instance;
	}
};

  

3. 饿汉版(Eager Singleton)

饿汉版(Eager Singleton):指单例实例在程序运行时被立即执行初始化

// version 1.3
class Singleton
{
private:
	static Singleton instance;
private:
	Singleton();
	~Singleton();
	Singleton(const Singleton&);
	Singleton& operator=(const Singleton&);
public:
	static Singleton& getInstance() {
		return instance;
	}
}

// initialize defaultly
Singleton Singleton::instance;

  




有些内容转载自知乎:

C++ 单例模式

https://zhuanlan.zhihu.com/p/37469260

posted on 2020-08-23 15:32  lialin  阅读(258)  评论(0编辑  收藏  举报

导航