首页  >  文章  >  后端开发  >  为什么 C 不使用嵌套异常来处理析构函数抛出的异常?

为什么 C 不使用嵌套异常来处理析构函数抛出的异常?

Barbara Streisand
Barbara Streisand原创
2024-11-01 01:29:02382浏览

Why doesn't C   use nested exceptions to handle exceptions thrown from destructors?

为什么 C 不使用嵌套异常从析构函数抛出异常?

理解问题

从析构函数抛出异常引入了一个困境:当异常已经发生时该怎么办?覆盖现有异常或在现有异常中嵌套新异常是潜在的解决方案,但我们决定使用 std::terminate 终止将是标准方法。

考虑嵌套异常

C 11 引入了 std::nested_exception 功能,该功能可以通过将旧异常嵌套在新异常中来解决该问题。然而,这个想法并没有实现。

未实现的原因

在此上下文中不使用嵌套异常的一个原因是 std::nested_exception 具有用途非常有限,只有一个已知的实际应用:创建完全注释的调用堆栈。

此示例演示了嵌套异常如何提供一种在调试期间添加上下文和查明错误的便捷方法:

<code class="cpp">#include <iostream>
#include <sstream>
#include <exception>

void rethrow(const std::string& context, ...) {
    std::ostringstream ss;
    ss << context;
    auto sep = " : ";
    (void) ((ss << sep << args), sep = ", ", 0)...);
    try {
        std::rethrow_exception(std::current_exception());
    } catch(const std::invalid_argument& e) {
        std::throw_with_nested(std::invalid_argument(ss.str()));
    } catch(const std::logic_error& e) {
        std::throw_with_nested(std::logic_error(ss.str()));
    } catch(...) {
        std::throw_with_nested(std::runtime_error(ss.str()));
    }
}

int main() {
    try {
        outer("xyz");
        outer("abcd");
    } catch(std::exception& e) {
        print_exception(e);
    }
    return 0;
}

void print_exception(const std::exception& e, std::size_t depth = 0) {
    std::cerr << "exception: " << std::string(depth, ' ') << e.what() << '\n';
    try {
        std::rethrow_if_nested(e);
    } catch (const std::exception& nested) {
        print_exception(nested, depth + 1);
    }
}</code>

预期输出:

exception: outer : abcd
exception:  inner : abcdabcd
exception:   really_inner
exception:    too long

上面的示例展示了异常的嵌套,并演示了该技术如何帮助跟踪错误和理解调用堆栈。

尽管在此示例中嵌套异常很有用在特定场景中,由于使用 std::terminate 终止的简便性和可靠性,可能会决定不在析构函数异常的情况下使用它们。

以上是为什么 C 不使用嵌套异常来处理析构函数抛出的异常?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn