《Effictive C++》学习笔记 — 资源管理

条款13 — 以对象管理资源

1、使用goto的资源管理

在C和C++中对goto关键字的使用被诟病违背了结构化编程。然而,由于内存资源是由我们自己维护的,很多情况下我们又不得不使用goto保证内存的释放。

#include <iostream> 
using namespace std;

class CLS_Test
{
   
public:
	bool open()
	{
   
		return true;
	}

	bool start()
	{
   
		throw exception("start exception");
	}

	bool stop()
	{
   
		return false;
	}

	~CLS_Test()
	{
   
		cout << "release CLS_Test" << endl;
	}
};

void test()
{
   
	CLS_Test* pTest = new CLS_Test;
	if (!pTest)
	{
   
		goto END;
	}

	if (!pTest->open())
	{
   
		goto END;
	}

	try
	{
   
		if (!pTest->start())
		{
   
			goto END;
		}
	}
	catch (exception e)
	{
   
		cout << e.what() << endl;
		goto END;
	}

	if (!pTest->stop())
	{
   
		goto END;
	}
END:
	if (pTest)
	{
   
		delete pTest;
	}
}

int main()
{
   
	test();
}

在这里插入图片描述
一方面,为了使代码清晰易读,我们需要使用goto语句;同时,我们也是为了避免资源泄漏。这么一看其实goto可以跟java中的finally类比。
即使如此,以后可能有其他人对此段代码进行修改。若他们没有注意到此处的资源管理,而是在中间return了,就有可能导致资源泄漏。就像我们前面讨论过的,良好的编程风格固然可以避免一些问题。然而如果我们能从语法角度直接杜绝问题产生的可能性,总是更好的。

2、以对象管理资源

这种思想基于以下的事实:在函数运行结束后,临时类对象的析构函数一定会被自动调用。
因此,我们可以使用C++标准库中提供的智能指针来管理堆中的内存。

void test()
{
   
	std::auto_ptr<CLS_Test> pTest(new CLS_Test);
	if (!pTest->open())
	{
   
		return;
	}

	try
	{
   
		if (!pTest->start())
		{
   
			return;
		}
	}
	catch (exception e)
	{
   
		cout << e.what() << endl;
	}

	if (!pTest->stop())
	{
   
		return;
	}
}

(1)获得资源后立刻放进管理对象内

在这里我们明确提出管理对象的概念。智能指针本身是一个对象,但是其作用只是用于管理我们在堆上分配的内存。通常情况下,我们会将内存块作为智能指针的初值。因此通常我们认为:资源取得时机便是初始化时机(RAII)。 这样的做法也是最安全有效的。

(2)运用析构函数确保资源释放

在智能指针内部,会在析构函数里对其管理的内存进行释放。我们也正是使用了析构函数的必然执行来保障了内存的管理。那么对于析构函数中可能抛出的异常呢?我们前面在前面讨论过,客户有机会处理异常。

3、C++标准库中的智能指针

简单讨论下C++中的四种智能指针。

(1)auto_ptr

最早的一个智能指针。它在C++11中被标注为过时,C++17中已移除。前面我们的例子就是使用它实现的,因此我们简单说下它的一个特性:
同时保证只有一个智能指针对象拥有指针的控制权。

auto_ptr& operator=(auto_ptr& _Right) noexcept {
   
    reset(
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值