设计模式-------单例模式

本文介绍了单例模式的概念及其三种实现方式:饿汉模式、懒汉模式及带双重检查的懒汉模式。通过代码示例详细解析了每种模式的特点与适用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介

单例模式是最常用的设计模式之一,它属于创建型模式,它提供一种创建对象的最佳方式。保证一个类仅有一个

实例,并提供一个访问它的全局访问点。

单例模式不同的实现方式

1.饿汉模式:

class Singleton
{
public:
	static Singleton* GetInstance()
	{
		return instance;
	}
private:
	Singleton()
	{
		cout<<"Singleton()"<<endl;
	}
	static Singleton*  instance ;
};
Singleton* Singleton::instance= new Singleton();//静态数据成员必须初始化

int main()
{
	cout << "main run..." << endl; //验证静态对象的创建在main之前
	Singleton* _s1 = Singleton::GetInstance();
	Singleton* _s2 = Singleton::GetInstance();
	cout << _s1 << endl;
	cout << _s2 << endl;
	//返回的是同一个对象
	system("pause");
	return 0;
}

运行结果:

结论:饿汉模式顾名思义就是用空间换时间,并且是线程安全的。

2.懒汉模式

class Singleton
{
public:
	static Singleton* GetInstance()
	{
		if (instance == NULL) {
			instance = new Singleton();
			cout << "Obj success for" << endl;
		}
		else
			cout << "Create failure" << endl;
		return instance;
	}
private:
	Singleton()
	{
		cout << "Singleton()" << endl;
	}
	static Singleton*  instance;
};
Singleton* Singleton::instance =NULL;//静态数据成员必须初始化
int main()
{
	cout << "main run..." << endl; //验证静态对象的创建在main之前
	Singleton* _s1 = Singleton::GetInstance();
	Singleton* _s2 = Singleton::GetInstance();
	cout << _s1 << endl;
	cout << _s2 << endl;
	//返回的是同一个对象
	system("pause");
	return 0;
}

运行结果:

结论:懒汉模式用饿汉模式相反,它是用时间换取空间,但线程不安全。

3.带双重检查的懒汉模式

class Singleton
{
public:
	volatile static Singleton* GetInstance()
	{
		//第一次检查实例是否存在
		if (instance == NULL) 
		{
			lock_guard<mutex> lock(_mtx);//调用即加锁,离开大括号作用域自动解锁  
			//第二次检查实例是否存在
			if (instance == NULL)
			{
				instance = new Singleton();
				cout << "Obj success for" << endl;

			}
			else
				cout << "Create failure" << endl;

		}
		
		return instance;
	}
private:
	Singleton()
	{
		cout << "Singleton()" << endl;
	}
	volatile static Singleton*  instance;   //设置volatile关键字,防止被编译器优化
	static mutex _mtx;
};
volatile Singleton* Singleton::instance = NULL;//静态数据成员必须初始化
mutex Singleton::_mtx;

int main()
{
	cout << "main run..." << endl; //验证静态对象的创建在main之前
	volatile Singleton* _s1 = Singleton::GetInstance();
	volatile Singleton* _s2 = Singleton::GetInstance();
	cout << _s1 << endl;
	cout << _s2 << endl;
	//返回的是同一个对象
	system("pause");
	return 0;
}

运行结果:

结论:先解释下为什么在同步块内还要再检验一次,因为可能会有多个线程一起进入同步块外的 if,如果在同步块内不进行二次检验的话就会生成多个实例了。这种实现版本,不仅安全且在多线程情况下能保持高性能。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值