离开析构函数的一个例外异常案例

时间:2010-02-09 01:19:52

标签: c++ exception-handling destructor

我正在开发一个简单的类来管理HKEY的生命周期。

class Key
{
    HKEY hWin32;
public:
    Key(HKEY root, const std::wstring& subKey, REGSAM samDesired);
    Key(const Key& other);
    ~Key();
    Key& operator=(const Key& other);
    Key& swap(Key& other);
    HKEY getRawHandle() { return hWin32; };
};

 //Other Methods....

Key::~Key()
{
    LONG errorCheck
        = RegCloseKey(hWin32);
    /*
     * I know it's generally bad to allow exceptions to leave destructors,
     * but I feel that if RegCloseKey() is going to fail, the application
     * should be terminated. (Because it should never fail.)
     */
    if (errorCheck != ERROR_SUCCESS)
        WindowsApiException::Throw(errorCheck);
}

这是有效的推理吗?我不知道如何将RegCloseKey()的失败传达给被叫方。

3 个答案:

答案 0 :(得分:5)

RegCloseKey的失败更多是assert情况,而不是需要传递给调用链的错误。你想在调试版本中坐下来立即注意

但是失败信息会对调用者有什么好处呢?他该怎么办呢?

答案 1 :(得分:0)

一般 不好。它 坏了!

如果抛出异常,则会解除堆栈,直到满足catch子句。如果您的一个Key对象在堆栈中,它的析构函数将被调用。如果它抛出你同时有2个例外。在这种情况下,会调用terminate(),因此您不会有机会对任何一个例外做任何事情。

答案 2 :(得分:0)

以这种方式思考 - 忽略错误消息的原因很糟糕,因为如果某些内容确实失败,那么您应该处理它并使用它做某事(例如警告用户,重试,等等)。但是在这种情况下,你并没有真正处理它 - 你只是终止应用程序(这也是不好的做法)。

我建议肯定有一个断言来确保你在调试版本中捕获任何东西都会很好。使用OutputDebugString写出一些内容可能是发布版本的好主意。这样你就不会在发生错误时忽略应用程序,你注意到了它,但你没有终止应用程序......

在没有任何警告或解释的情况下终止应用程序只会让用户感到困惑和烦恼......你会如何向用户解释 - “好吧,我无法解释的事情应该永远不会发生,我不能忽视它,所以我必须立即退出应用程序!“?

我想我的观点是,泄漏手柄虽然糟糕,但比意外的应用程序关闭要糟糕得多。