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

Posted sanqima

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单例模式的懒汉模式与饿汉模式之间的对比 C++相关的知识,希望对你有一定的参考价值。

    单例模式,是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种创建方法

以上是关于单例模式的懒汉模式与饿汉模式之间的对比 C++的主要内容,如果未能解决你的问题,请参考以下文章

单例模式详解:懒汉式与饿汉式

单例模式---懒汉模式与饿汉模式

单例设计模式的懒汉式与饿汉式

设计模式:单例模式,懒汉与饿汉(转)工厂模式

单例模式之懒汉式与饿汉式

单例模式,饿汉与懒汉