C++设计模式:单例模式(饿汉模式+懒汉模式)

前言

设计模式(Design Pattern)是一套经过分类的,被反复使用的,代码设计经验的总结。 为什么会产生设计模式这个概念呢?随着时间的沉淀,以及前人的总结,我们发现代码设计也是有规律的,一类特定的问题会被一种特定的模式解决,这就衍生出了设计模式的概念。

使用设计模式的目的:为了代码的可重用性以及可靠性。

设计模式是软件工程的基石脉络,如同大厦的结构一样,设计模式使代码编写真正工程化。

一:单例模式

单例模式即一个类在全局中(进程)只能创建一个实例。

单例模式有两种实现模式:懒汉模式和饿汉模式。

1.1 懒汉模式

懒汉模式:第一次使用实例对象时再创建实例对象。

代码演示:

#include
#include
#include
#include
using namespace std;

class Singleton{
public:
	// 静态成员函数只能访问静态成员变量
	static Singleton* GetInstance(){
		if (_pinst == nullptr)
		// 局部域(通过作用域来控制解锁时机)
		{
			// _mtx.lock();
			unique_lock<mutex> lock(_mtx); // (保护操作的原子性)
			if (_pinst == nullptr)
				// 锁只需要保护第一次(需要进行双检查)
				_pinst = new Singleton;
			// _mtx.unlock();
		}
		return _pinst;
	}

	Singleton(const Singleton& s) = delete;

	// 实现一个内嵌垃圾回收类
	class CGarbo {
	public:
		~CGarbo(){
			if (Singleton::_pinst)
				delete Singleton::_pinst;
		}
	};

	// 定义一个静态成员变量,程序结束时,系统会自动调用它的析构函数从而释放单例对象
	static CGarbo Garbo;

private:
	// 构造函数私有化
	Singleton(){}

	// 防拷贝
	Singleton(Singleton const&);
	Singleton& operator=(Singleton const&);

	static Singleton* _pinst;
	static mutex _mtx;
};

Singleton* Singleton::_pinst = nullptr;
mutex Singleton::_mtx;
Singleton::CGarbo Garbo;
1.2 饿汉模式

饿汉模式:程序启动时就创建一个唯一的实例对象。

如果这个单例对象在多线程高并发环境下频繁使用,性能要求较高,那么显然使用饿汉模式来避免资源竞争,提高响应速度更好。

代码演示:

#include
#include
#include
#include
using namespace std;

// 饿汉模式
class Singleton
{
public:
	static Singleton* GetInstance(){
		return &m_instance;
	}

private:
	// 构造函数私有
	Singleton(){};

	Singleton(Singleton const&) = delete;
	Singleton& operator=(Singleton const&) = delete;

	// 单例对象
	static Singleton m_instance;
};

// 在程序入口之前就完成单例对象的初始化,不用考虑线程安全的问题。
Singleton Singleton::m_instance; 
1.3 懒汉模式和饿汉模式的对比

懒汉模式:

优点:懒汉模式在使用实例的时候才进行创建,不会影响程序的启动。并且多个单例实例启动顺序自由控制。

缺点:懒汉模式实现复杂。并且需要考虑线程安全问题

饿汉模式:

优点:饿汉模式实现简单,并且在程序启动时已经完成了对单例对象的初始化,不需要考虑线程安全问题。

缺点:饿汉模式在程序启动时完成了对单例对象的初始化,会在一定程度上影响程序启动。静态成员变量无法确定单例的创建初始化顺序,多个单例类对象实例启动顺序不确定。

小结:

实际中懒汉模式还是应用更为广泛

你可能感兴趣的:(C++,单例模式)