代码之家  ›  专栏  ›  技术社区  ›  Gal Goldman

调用函数的析构函数,该函数可以在C中引发异常++

  •  10
  • Gal Goldman  · 技术社区  · 15 年前

    shouldn't 从析构函数抛出异常。

    5 回复  |  直到 15 年前
        1
  •  20
  •   Stack Overflow is garbage    9 年前

    是的,这是合法的。不能有例外 逃跑

    (从技术上讲,异常也可以从析构函数调用中转义。如果在堆栈展开过程中由于引发了另一个异常而发生这种情况, std::terminate 被称为。因此,标准对其进行了很好的定义,但它是一个 坏主意。)

        2
  •  4
  •   Loki Astari    15 年前

    以标准库中的std::fstream类为例。

    • 析构函数可以调用close(),但析构函数不会抛出(它将吞并任何异常)。

    其概念是,如果析构函数调用任何可以抛出的方法,那么这些方法应该是公共的。因此,如果对象的用户想要检查异常,他们可以使用公共方法来处理异常。如果他们不关心异常,那么就让析构函数处理这个问题。

    {
        std::fstream   text("Plop");
        // Load Text.
    
        // I don't care if the close fails.
        // So let the destructor handle it and discard exceptions
    }
    
    
    
    {
        // If this fails to write I should at least warn the user.
        // So in this case I will explicitly try and close it.
        try
        {
            std::ofstram    password("/etc/password");
            // Update the password file.
    
            password.close();
        }
        catch(...)
        {
              Message.ShowDialog("You failed to update the Password File");
        }
    }
    
        3
  •  2
  •   Community Neeleshkumar S    7 年前

    您可以在这里找到一些示例: https://software.intel.com/sites/products/documentation/doclib/iss/2013/sa-ptr/sa-ptr_win_lin/GUID-D2983B74-74E9-4868-90E0-D65A80F8F69F.htm

    当没有进行堆栈展开时,异常可以在不调用std::terminate()的情况下离开析构函数。但是,对于在堆上分配的对象,这将导致内存泄漏,因为将异常抛出其析构函数的对象不会调用“运算符删除”。令人惊讶的是,在这种情况下仍然会调用基类的析构函数: What happens to base class destructor if a derived class destructor throws an exception

    如果异常在析构函数内部被捕获(以便异常不会离开析构函数),那么即使另一个异常的堆栈展开正在进行,也没有问题。下面将更深入地描述该案例: http://bin-login.name/ftp/pub/docs/programming_languages/cpp/cffective_cpp/MEC/MI11_FR.HTM

        4
  •  0
  •   Matt Price    15 年前

    答案很简单,决不允许dtor出现异常!

    std::terminate 调用时,请注意,您可以将自己的处理程序放入 终止 打电话 std::set_terminate 终止 是调用abort。

    更复杂的是,大多数想要保证其异常安全性的函数,主要是基本保证或强保证,依赖于自身的底层类型,而不是抛出它们的dtor*

    真正的问题是,当这个错误发生时,您的程序将处于什么状态?你怎样才能恢复?这种恢复应该在哪里进行?你需要看看你的具体案例,解决这些问题。有时候捕捉异常并忽略它是很好的。其他时候,你需要发出一些危险信号。

    所以答案是:C++允许在dtor中抛出异常,但不应该允许它转义。

    *这里有一个简短的介绍 synopsis article )

    1. 强壮的,没有什么)。

    最基本的保证是它失败了 但没有发生泄漏并受到影响 对象/模块仍然是可破坏的 (必须是可预测的)状态。

    强有力的保证包括 语义:失败的操作保证 这意味着没有副作用,影响 对象,包括有效性或 相关辅助对象的内容 例如指向 被操纵的容器。

    nothrow担保意味着 操作将不会引发异常。

        5
  •  -1
  •   Brian    15 年前

    this page 从C++常见问题解答Lite中获取信息。基本的答案是,“不要这样做。”你计划在哪里捕捉这个异常?无论您在捕获该异常时打算做什么,只需使用函数调用或其他方式(例如,记录该异常或设置一个警告用户的标志或其他方式)即可。从析构函数抛出异常可能导致整个程序终止。