单例模式与call_once;

单例模式的概念:

整个项目中,有某个或者某些特殊的类,只能创建一个属于该类的对象。

下面是单例类的实现代码:

#include <iostream>
using namespace std;

class A {

private:
	A() {}
	static A* m_A;
public:
	static A* GetInstance() {
		if (m_A == NULL) {
			m_A = new A();
			static B cl;
		
		}
		return m_A;
	}
	//释放对象
	class B {
	public:
		~B() {
			if (A::m_A) {
				delete A::m_A;
				A::m_A = NULL;
			}
		}


	};
	void func() {
	
		std::cout << "ww" << std::endl;
	}

};

//静态成员的初始化操作
A* A::m_A = NULL;

void main() {

	A *p_a = A::GetInstance();
	A *p_b = A::GetInstance();
	//创建再多的指针也还是同一个地址;
}

1.将类的构造函数设置为私有的,同时申请静态成员函数(公有)和静态成员变量(私有);

2.怎么释放申请的单例类对象的内存呢,在类中嵌套一个类对象,在嵌套的类对象中析构函数中 释放申请的变量。(将嵌套类对象放在大类的静态成员函数中(以静态对象存在哦!确保对象是在程序运行结束后释放的));


当单例碰到了多线程,会有什么问题,比如两个线程中同时访问GetInstance(),这就会出现问题,会同时创建多个对象????

那解决措施自然 会想到 互斥量来锁一下来解决这个问题!

GetInstance()函数是只是初始化会被调用一次的,所以如下的操作不太行,效率不行!

#include <iostream>	
#include <mutex>
using namespace	std;

mutex myMutex;
//懒汉模式
class Singelton
{
public:
	static Singelton * getInstance() {     		
		lock_guard<mutex> myLockGua(myMutex);
		if (instance == NULL) {
			instance = new Singelton;
		}	
		return instance;
	}
private:
	Singelton() {}
	static Singelton *instance;
};
Singelton * Singelton::instance = NULL;


所以就有了双重锁定解决效率问题!

#include <iostream>	
#include <mutex>
using namespace	std;

mutex myMutex;

class Singelton
{
public:
	static Singelton * getInstance() {
         //双重锁定 提高效率
		if (instance == NULL) {
			lock_guard<mutex> myLockGua(myMutex);
			if (instance == NULL) {
				instance = new Singelton;
			}
		}
		return instance;
	}
private:
	Singelton() {}
	static Singelton *instance;
};
Singelton * Singelton::instance = NULL;




这样算是解决了问题!

同样的c++11给我们提供了一个解决方案 std::call_once 当然要结合std::once_flage 一起,具体操作就是  将只要初始化一次的语句,写入一个函数中,在调用这对类std 解决;代码如下:

once_flag g_flag;
class Singelton
{
public:
    static void CreateInstance()//call_once保证其只被调用一次
    {
        instance = new Singelton;
    }
    //两个线程同时执行到这里,其中一个线程要等另外一个线程执行完毕
	static Singelton * getInstance() {
         call_once(g_flag, CreateInstance);
         return instance;
	}
private:
	Singelton() {}
	static Singelton *instance;
};
Singelton * Singelton::instance = NULL;

部分 代码 参考博客:https://blog.csdn.net/qq_38231713/article/details/106092538

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值