设计模式-单例模式

单例模式

整个项目中有某个或者某些特殊类 只能创建一个对象 不能创建多个

单例类

class A
{
private:
	A() {};//直接将构造函数私有化 这样就不能通过A a = new A;来实现对类对象的创建
private:
	static A* m_instance;//这个静态类对象就是我们能创建的那个唯一的一个类对象 设置为静态就是改变对象的作用于 归属于整个类 
public:
	/*这个函数就是用来创建唯一的一个类对象*/
	static A* getInstance()
	{
		if (m_instance == NULL)
		{
			m_instance = new A();
			static GarColl GC;//当程序退出的时候就会调用这个对象的析构函数 自然就会把m_instance对象删除掉
		}
		return m_instance;
	}
	
	/*类中的类 用来对A::m_instance进行释放*/
	class GarColl
	{
	public:
		~GarColl()
		{
			if (A::m_instance != NULL)
			{
				delete A::m_instance;
				A::m_instance = NULL;
			}
		}

	};
};
A* A::m_instance = NULL;//类中的静态变量就需要在类外先初始化 但是这个是私有对象 可以这样初始化吗
int main()
{
	A *a = A::getInstance();//这样就创建了
	A *b = A::getInstance();//其实是一个指针对象 存储的是同一个地址
	cout<<"a:"<<a<<endl;//a:00000127D6C73320
	cout<<"b:"<<b<<endl;//b:00000127D6C73320
	return 0;
}

单例设计模式会面临的问题(双重锁定解决办法)

在线程中创建单例类对象 此时就需要对get_instance()进行互斥
因为如果不做互斥就会导致 如果两个线程依次越过了m_instance == NULL判断就会导致对m_instance静态对象new了两次 其中一个线程获取的地址肯定就错误了
很明显 在创建之前加一个锁就行了

static A* getInstance()
{
	std::unique_lock<std::mutex>uniqueTex(mtex);//进行一个加锁
	if (m_instance == NULL)
	{
		//std::unique_lock<std::mutex>uniqueTex(mtex);//如果在这里加锁没有意义 同样会new两次
		m_instance = new A();
		static GarColl GC;//当程序退出的时候就会调用这个对象的析构函数 自然就会把m_instance对象删除掉
	}
	return m_instance;
}

但是这样你就会发现 本来我们只需要在线程每次初始化的时候加个锁就行了 但是现在只要执行了这个函数就会加锁解锁一次 效率很低
解决办法:双重锁定

static A* getInstance()
{
	if (m_instance == NULL)
	{
		std::unique_lock<std::mutex>uniqueTex(mtex);//这样就可以了
		if (m_instance == NULL)
		{
			m_instance = new A();
			static GarColl GC;//当程序退出的时候就会调用这个对象的析构函数 自然就会把m_instance对象删除掉
		}
	}
	return m_instance;
}

std::call_once

call_once能保证函数在程序中只被调用一次 在效率上比互斥量更高消耗资源更少
如果call_once包含的函数被调用 则定义的std::once_flag标记则会被设置为已调用 此时这个被包含的函数就不能再被调用
std::once_flag是一个结构 系统定义的标记

std::once_flag g_flag;
void fun()
{
}
void start()
{
	std::call_once(g_flag,fun);	
}
int main()
{
	thread mobj1(start);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值