资源泄漏问题
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来释放资源。