单例模式的懒汉模式与饿汉模式之间的对比 C++

52 篇文章 2 订阅
7 篇文章 0 订阅

    单例模式,是GOF 23种设计模式中的一种,有2种方法可以实现单例模式,分为懒汉式、饿汉式,它们的区别如下:

对比懒汉式单例饿汉式单例
创建时间需要时才创建,在程序运行之后调用getInstance()创建的在程序编译时,就创建了单例对象
是否加锁需要加锁不需要加锁
线程安全使用std::call_one、static member等方法,可以规避线程安全问题在主函数之前,静态初始化,可以保证线程安全
实现难度比较复杂比较简单

1、懒汉式单例

    这里采用可调用函数std:call_one()来保证单例只创建一次,从而保证线程安全。
//singleton.cpp

#include <iostream>
#include <memory>
#include <mutex>

using namespace std;

static std::once_flag  g_flag;
//--------------------- A:懒汉式 -----------------------------------
class Singelton {
public:
	static Singelton* getInstance() {
		if (m_instance == NULL) {
			//m_instance = new Singelton;
			std::call_once(g_flag, initSingleton);
		}
		m_count++;
		return m_instance;
	}

	int getCount(){
		return m_count;
	}

	~Singelton()
	{
		if (m_instance != NULL) {
			delete m_instance;
			m_instance = NULL;
		}
	}

private:
	Singelton(){
		m_instance = NULL;
		m_count    = 0;
		cout << "call Singleton()..." << endl;
	}

	static void initSingleton(){
		m_instance = new Singelton;
	}

	static Singelton*      m_instance;
	static int             m_count;
};

//初始化
//懒汉式,在程序调用getInstance时,才创建对应的实例
Singelton *Singelton::m_instance = NULL;
int Singelton::m_count = 0;

2、饿汉式单例

    通过静态初始化,在进入main()函数之前,单例就已经创建了,天然就具有线程安全性。
//singleton2.cpp


//--------------------- B:饿汉式 -----------------------------------
class Singelton2 {
public:
	static Singelton2* getInstance(){
		m_count++;
		return m_instance;
	}

	int getCount(){
		return m_count;
	}

	~Singelton2()
	{
		if (m_instance != NULL) {
			delete m_instance;
			m_instance = NULL;
		}
	}


private:
	Singelton2(){
		m_instance = NULL;
		m_count = 0;
	}
	static Singelton2* m_instance;
	static int         m_count;
};

//饿汉式的单例,在程序编译的时候,就已经创建好了
Singelton2* Singelton2::m_instance = new Singelton2;
int Singelton2::m_count = 0;

3、完整代码

//single.cpp

#include <iostream>
#include <memory>
#include <mutex>

using namespace std;

static std::once_flag  g_flag;
//--------------------- A:懒汉式 -----------------------------------
class Singelton {
public:
	static Singelton* getInstance() {
		if (m_instance == NULL) {
			//m_instance = new Singelton;
			std::call_once(g_flag, initSingleton);
		}
		m_count++;
		return m_instance;
	}

	int getCount(){
		return m_count;
	}

	~Singelton()
	{
		if (m_instance != NULL) {
			delete m_instance;
			m_instance = NULL;
		}
	}

private:
	Singelton(){
		m_instance = NULL;
		m_count    = 0;
		cout << "call Singleton()..." << endl;
	}

	static void initSingleton(){
		m_instance = new Singelton;
	}

	static Singelton*      m_instance;
	static int             m_count;
};

//初始化
//懒汉式,在程序调用getInstance时,才创建对应的实例
Singelton *Singelton::m_instance = NULL;
int Singelton::m_count = 0;


//--------------------- B:饿汉式 -----------------------------------
class Singelton2 {
public:
	static Singelton2* getInstance(){
		m_count++;
		return m_instance;
	}

	int getCount(){
		return m_count;
	}

	~Singelton2()
	{
		if (m_instance != NULL) {
			delete m_instance;
			m_instance = NULL;
		}
	}


private:
	Singelton2(){
		m_instance = NULL;
		m_count = 0;
	}
	static Singelton2* m_instance;
	static int         m_count;
};

//饿汉式的单例,在程序编译的时候,就已经创建好了
Singelton2* Singelton2::m_instance = new Singelton2;
int Singelton2::m_count = 0;

int main(){
	//---------------------------- 1) 懒汉式的单例模式  ------------------------
	Singelton *singer = Singelton::getInstance();
	cout << "call times:"<<singer->getCount() << endl;
	Singelton *singer2 = Singelton::getInstance();
	cout << "call times:" << singer2->getCount() << endl;
	if (singer == singer2) {
		cout << "1.1 These two singes are the same!" << endl;
	}
	else {
		cout << "1.2 These two singes are not the same!" << endl;
	}


	//---------------------------- 2) 饿汉式的单例模式  ------------------------
	Singelton2 *singer3 = Singelton2::getInstance();
	cout << "call times:" << singer3->getCount() << endl;
	Singelton2 *singer4 = Singelton2::getInstance();
	cout << "call times:" << singer4->getCount() << endl;

	if (singer3 == singer4) {
		cout << "2.1 These two singes are the same!" << endl;
	}
	else {
		cout << "2.2 These two singes are not the same!" << endl;
	}

	system("pause");
	return 0;
}

    效果如下:

图(1) 单例模式的2种创建方法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sanqima

一键三连,多多益善

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值