c – Try / Catch块替换析构函数中的方法块

我最近的任务是在代码的一部分中查找内存泄漏.泄漏最终出现在特定对象的析构函数中……我发现了一些非常奇怪的东西.一位前同事写道:
File::~File()
try
{
    Clear();
}
catch (...)
{
    Log("caught exception");
}

文件类继承自一些基类.我的第一个问题是:这是严格合法的C吗?它在Visual Studio 2008中编译,但我向几个朋友/同事展示了它们,并且它们相当惊恐,它的工作原理.

但它实际上并没有按预期工作:这个对象继承的基类有一个现在永远不会被调用的析构函数(而不是如果你只是将析构函数包装在常规方法块中,将try / catch作为一部分)那个方法).

任何人都可以尝试解释为什么允许这样做,以及为什么没有调用基类析构函数?这里的析构函数并没有抛出.

解决方法

这是一个功能尝试块,它是完全合法的.

例如,参见here.

你可以在一个函数中执行某些操作的唯一一次你在一个函数中的普通try块中无法做的事情就是捕获构造函数初始化列表中表达式抛出的异常(甚至你最终还是要抛出一些东西),但这不适用于此.

这个GOTW #66特别有趣,尽管它更多地集中在构造函数上.它包含这个“道德”:

Since destructors should never emit an exception,destructor function-try-blocks have no practical use at all.

只是为了补充说明,编写的代码将导致由于ISO / IEC 14882:2003 15.3 [except.handle] / 16而被捕获的任何异常:

The exception being handled is rethrown if control reaches the end of a handler of the function-try-block of a constructor or destructor. […]

但是,在函数try块的处理程序中为析构函数提供无参数返回是合法的 – 它只在构造函数函数try块中被禁止 – 这将抑制异常的重新抛出.因此,这些替代方案中的任何一个都可以防止异常离开析构函数.

File::~File()
try
{
    Clear();
}
catch (...)
{
    Log("caught exception");
    return;
}
File::~File()
{
    try
    {
        Clear();
    }
    catch (...)
    {
        Log("caught exception");
    }
}

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...