【C++ Exceptions】利用destructors避免泄露资源

资源泄漏问题

class dataHeader;
void process(istream& data)
{
	while(data)
	{
		dataHeader* = readData(data);
		dataHeader->processHeader();
		delete dataHeader;
	}
}
//如果没有调用delete,这个循环很快便会出现资源泄漏的问题
//若dataHeader->processHeader()发生异常,之后语句被跳过,不执行
//则dataHeader不会被删除,结果即导致资源泄漏

解决方法1:try-catch异常捕获

//避免上述情况的方法:
class dataHeader;
void process(istream& data)
{
	while(data)
	{
		dataHeader* = readData(data);
        try
        {
			dataHeader->processHeader();            
        }
		catch(...)					//捕获所有的exceptions
		{				    
            delete dataHeader;      //当exceptions被抛出,避免了资源泄露
            throw;                  //将exceptions传播给调用端
        }
		delete dataHeader;				//如果没有exceptinos被抛出,也要避免资源泄漏
	}
}

以上,try-catch语句块将程序搞乱,且被迫的重复撰写清理代码(如delete动作);
然而无论以正常方式还是异常方式离开processHeaader函数,都需要delete dataHeader不如集中在一处做此事,如解决方法2。

解决方法2:将释放资源的操作封装在析构函数里面

将“一定得执行的清理代码”转移到某个局部对象的destructor中:
因为局部对象不论如何结束的 ,总是会在函数结束时被析构。

具体的解决办法:
以一个“类似指针的对象”取代指针dataHeader。
(在对象被销毁时,可以令其destructor 调用 delete)

  • 将指针类型封装在一个类中,并在该类的析构函数中释放内存。
    这样即使抛出异常,该类的析构函数也会运行,内存也可以被适当的释放。
  • C++标准库提供了一个名为auto_ptr的类模板,用来完成这种功能。
void process(istream& data)
{
  while (data) {
    auto_ptr dataHeader(readData(data));
    dataHeader->processHeader(); 
    //无需调用语句delete dataHeader,出了作用域即调用析构函数
  }
}

总结

smart pointers(智能指针)核心思想:
以一个对象存放“必须自动释放的资源”,并依赖该对象的destrutor来释放资源。

你可能感兴趣的:(C++进阶,c++,笔记,开发语言)