单例模式

单例模式

目的:有且保证只有一个实例

应用场景:写日志等

问题的来源:

在new是对象产生的直接来源,为了只有实例化一个对象,那么只能将构造函数私有化才能控制对象的个数。

在构造函数私有化后,需要提供一个方法,让程序获取对象。


具体代码:

/*懒汉式*/
#include"afxmt.h"//同步操作时需要包含的头文件

class CSingleton
{

public:
	static CCriticalSection _cs;
	static CSingleton * _instance;//全局唯一实例
private:

	CSingleton()//私有化构造器
	{
	}

	~CSingleton()
	{

		if (_instance != nullptr)//多线程会出现问题
		{
			delete _instance;
			_instance = nullptr;
		}
	}
	/**
	*私有拷贝构造和赋值重载,保证唯一实例
	*/
	CSingleton(const CSingleton &);
	CSingleton & operator = (const CSingleton &);
public:
	static CSingleton* getInstance()//多线程会出现问题
	{
		if (_instance == nullptr)
		{
			_cs.Lock();
			if (_instance == nullptr)
			{
				_instance = new CSingleton();
			}
			_instance = new CSingleton();
			_cs.Unlock();
		}
		return _instance;
	}	
};



/*静态变量的初始化*/
CSingleton * CSingleton::_instance = nullptr;
CCriticalSection CSingleton::_cs;


其中私有化的成员变量:构造函数、拷贝构造,赋值重载。就是为了不能实例化对象。

if (_instance == nullptr)
		{
			_cs.Lock();
			if (_instance == nullptr)
			{
				_instance = new CSingleton();
			}
			_instance = new CSingleton();
			_cs.Unlock();
		}

首先判定是否为空,不为空加锁,在判定是否为空。主要是因为:锁的开销很大  所以需要先判定是否为空。释放的时候需要判定是否为空 才能释放指针。

/*饿汉式*/
class CSingleton2
{

public:
	static CCriticalSection _cs;
	static CSingleton2 * _instance;//全局唯一实例
private:

	 CSingleton2()//私有化构造器
	{
	}

	~CSingleton2()
	{
		delete _instance;
		_instance = nullptr;
	}
	/**
	*私有拷贝构造和赋值重载,保证唯一实例
	*/
	CSingleton2(const CSingleton2 &);
	CSingleton2 & operator = (const CSingleton2 &);
public:
	static CSingleton2* getInstance()//多线程会出现问题
	{
		return _instance;
	}

};
/*静态变量的初始化*/
CSingleton2 * CSingleton2::_instance = new CSingleton2();

<span style="font-family: Arial, Helvetica, sans-serif;">上面代码 不需要加锁,是因为在类加载时候就会实例话对象,就不会实例化多个对象。</span>

测试代码:
#include <iostream>
#include "Singleton.h"


using namespace std;




int main()
{




<span style="white-space:pre">	</span>CSingleton *s1 = CSingleton::getInstance();
<span style="white-space:pre">	</span>CSingleton *s2 = CSingleton::getInstance();


<span style="white-space:pre">	</span>cout << "-----------懒汉式单例模式-----------"<< endl;
<span style="white-space:pre">	</span>cout << "单例1的地址:" << s1 << endl;
<span style="white-space:pre">	</span>cout << "单例2的地址:" << s2 << endl<<endl;


<span style="white-space:pre">	</span>CSingleton2 *s3 = CSingleton2::getInstance();
<span style="white-space:pre">	</span>CSingleton2 *s4 = CSingleton2::getInstance();


<span style="white-space:pre">	</span>cout << "-----------饿汉式单例模式-----------" << endl;
<span style="white-space:pre">	</span>cout << "单例1的地址:" << s3 << endl;
<span style="white-space:pre">	</span>cout << "单例2的地址:" << s4 << endl;


<span style="white-space:pre">	</span>getchar();
<span style="white-space:pre">	</span>return 0;
}

注意:

在多线程使用单例,还是需要加锁。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值