微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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");
    }
}

原文地址:https://www.jb51.cc/c/117128.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐