C++ 单例模式(析构函数的使用)

一、说明

单例模式中,实例什么时候释放是一个很严肃的问题,尤其是资源没有释放的情况。今天突然注意到了这个问题。

二、错误示范

2.1 看似没有错误的写法

我们先来看一份代码。
.h文件

#pragma once

#include <iostream>

using namespace std;
class SingletonPattern
{
private:
	SingletonPattern();
public:
	~SingletonPattern();

private:
	static SingletonPattern* m_Instance;

public:
	static SingletonPattern* GetInstance();

	void display();
};



.cpp文件

#include "SingletonPattern.h"
SingletonPattern* SingletonPattern:: m_Instance = nullptr;
SingletonPattern::SingletonPattern()
{
	cout << "创建单例模式对象!" << endl;
}

SingletonPattern::~SingletonPattern()
{
	if (m_Instance != nullptr) {
		delete m_Instance;
		m_Instance = nullptr;
	}
	cout << "销毁单例模式对象!" << endl;
}

SingletonPattern *SingletonPattern::GetInstance()
{
	if (m_Instance == nullptr) {
		m_Instance = new SingletonPattern();
	}

	cout << "返回单例模式句柄!" << endl;
	return m_Instance;
}

void SingletonPattern::display()
{
	cout << "使用单例模式!" << endl;
}


测试

#include "SingletonPattern.h"

int main() {
	SingletonPattern* m_Test = SingletonPattern::GetInstance();
	m_Test->display();
	cin.ignore();
	return 0;
}

2.2 实际上隐藏巨大的bug

先不说这个析构函数会不会被调用,即使被调用后,析构函数和delete之间就会反复横跳(死循环),套娃是要不得的,程序是会崩溃的阿sir。

2.3 如何解决呢

当然又很多解决方式,例如

  1. 在外层直接手动delete
  2. getInstance里面不用new,而是直接static SingletonPattern m_Instance.
  3. 搞个垃圾回收的类Garbo

这里,我们重点说一下第三种的实现。

#pragma once

#include <iostream>

using namespace std;
class SingletonPattern
{

private:
	SingletonPattern();
	~SingletonPattern();
private:
	static SingletonPattern* m_Instance;

public:
	static SingletonPattern* GetInstance();

	void display();
private:
	class CGabor
	{
	public:
		~CGabor(){
			if (SingletonPattern::m_Instance){
				delete SingletonPattern::m_Instance;
				SingletonPattern::m_Instance = NULL;
			}
		}
	};
	static CGabor m_Gabor;
};



#include "single.h"
SingletonPattern* SingletonPattern:: m_Instance = nullptr;
SingletonPattern::CGabor SingletonPattern::m_Gabor;
SingletonPattern::SingletonPattern()
{
	cout << "创建单例模式对象!" << endl;
}

SingletonPattern::~SingletonPattern()
{
//可在此释放某些占用的资源
}

SingletonPattern *SingletonPattern::GetInstance()
{
	if (m_Instance == nullptr) {
		m_Instance = new SingletonPattern();
	}

	cout << "返回单例模式句柄!" << endl;
	return m_Instance;
}

void SingletonPattern::display()
{
	cout << "使用单例模式!" << endl;
}


#include "single.h"
int main() {
	SingletonPattern* m_Test = SingletonPattern::GetInstance();
	m_Test->display();
	cin.ignore();
	
	return 0;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值