再论单例模式 之 懒汉模式

之前的一篇单例模式帖子:https://blog.csdn.net/weixin_41318405/article/details/84586957

这次探讨懒汉模式细节问题。

先来看一段代码

class Data
{
public:
	Data()
	{
		std::cout << this  << "Data()\n";
	}
	~Data()
	{
		std::cout << this <<"~Data()\n";
	}
};

int main()
{
	Data *d1 = new Data;
	Data d2;
	delete d1;
	return 0;
}

打印结果

从上述结果可以看出:(1)类对象指针在new的时候调用构造函数,但是程序结束不会自动销毁调用析构函数,需要用户手动调用析构函数。(2)类对象在定义会调用构造函数,程序结束会自动调用析构函数

说了这么多,这些到底对懒汉模式有什么用呢?

接下来看单例模式之懒汉模式,先上代码

class Singleton
{
public:
	static Singleton* GetInstance()
	{
		//此处两层判断,为了就是提高效率
		//此处使用到了锁,为了就是保证线程安全(同步和互斥)
        /*if (nullptr == m_pInstance)
		{
			m_pInstance = new Singleton;
		}*/
		if (nullptr == m_pInstance)
		{
			m_tex.lock();
			if (nullptr == m_pInstance)
			{
				m_pInstance = new Singleton;
			}
			m_tex.unlock();
		}
		return m_pInstance;
	}
	
	//定义一个内部类。程序结束回收对象,因为是new申请了空间
	class cycle
	{
	public:
		~cycle()
		{
			if (m_pInstance != nullptr)
			{
				delete m_pInstance;
				m_pInstance = nullptr;
			}
		}
	private:
        //定义一个静态回收类对象
		static cycle endflag;
	};
	
	Singleton(const Singleton& s) = delete;
	Singleton operator=(Singleton& s) = delete;
private:
	Singleton(){}
	static Singleton *m_pInstance;//单例对象指针
	static mutex m_tex;
};
Singleton* Singleton::m_pInstance = nullptr;
mutex Singleton::m_tex;
Singleton::cycle Singleton::cycle::endflag;
 
void fun(int n)
{
	cout << Singleton::GetInstance() << endl;
}
 
int main()
{
	thread t1(fun, 1);
	thread t2(fun, 2);
	thread t3(fun, 3);
	t1.join();
	t2.join();
	t3.join();
	return 0;
}

1. 此处没有使用单例模式的析构函数释放m_pInstance,而是使用了一个内部回收类?

如果使用单例模式Singleton的析构函数delete m_pInstance,因为delete释放的是自定义类型,所以导致循环调用析构函数,最终造成栈溢出。

2. 单例对象本质来时一个类对象指针,所以它的释放权利已经交给了用户,但是现在用户也不能通过调用析构函数释放了。

因为类对象(不是类对象指针)在程序结束自动调用析构函数,所以使用这一思想,通过创建一个静态的内部类对象,在其析构函数内销毁单例对象指针,这样就不会导致内存泄漏。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_41318405

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值