gpt4 book ai didi

c++ - C++ 异常中的异常

转载 作者:可可西里 更新时间:2023-11-01 15:39:19 25 4
gpt4 key购买 nike

在使用 C# 或 Java 时,我曾经创建异常类,其中包含其他异常作为类成员。例如:

public class MyException : Exception {
private MyException ex;
private String message;

public String what() {
return this.message;
}

public String stack() {
if(ex != null) {
StringBuilder s;
s.append(this.what());
s.append(this.ex.stack());
return s.toString();
}

return this.what();
}
}

我一直在寻找关于同一主题但对于 C++ 的示例,但我找不到任何示例(也许我没有搜索正确的术语,因为您可以看到这个问题的标题不是很花哨)。

无论如何,在 C++ 中执行此操作的正确方法是什么?是将内部异常存储为指针还是引用? (我想我可能需要一个指针,所以当它是第一个异常时它可以为空)。当我引发异常时,它应该作为使用 new 创建的指针吗?

编辑:也许我写的有点令人困惑,或者不是众所周知的(被接受的)编程实践。因此,我将指定我打算如何通过代码片段使用此类:

 try {
// Code that throws an exception of type MyException
} catch(MyException ex) {
MyException another = new MyException();
another.setEx(ex);
another.setMessage("A message that explains where the other exception was caught and on what conditions");

throw another;
}

最佳答案

对于 C++03 中的标准异常,没有正确的方法来做到这一点,因为它们被设计为以多态方式使用,但不能被克隆。因此,如果您捕捉到 std::exception const& e,您可以存储一个拷贝,但这将导致切片,丢失所有有用的信息。您不应该存储异常的指针或引用,因为一旦离开 catch 子句,它的生命周期就会结束(假设您不重新抛出原始异常).

如果您知道可以抛出的每一种类型并测试它们,您就可以绕过这个限制,但这不是一个好的设计(即它颠覆了多态性)。编写您自己的可以克隆的基异常类并捕获它更有意义。但是,如果您捕获到来自其他人代码的 std::exception,您仍然会遇到问题。

此时我不得不提到 Boost.Exception .它使您可以轻松编写自己的异常层次结构并提供各种实用程序,其中包括 boost::exception_ptr。然后你可以这样做:

typedef boost::error_info<struct tag_nested_exception, boost::exception_ptr>
nested_exception;

// ...
catch(...) {
// better: use BOOST_THROW_EXCEPTION
throw your_exception_type() << nested_exception( boost::current_exception() );
}

这非常有用,boost::diagnostic_info 支持它并将为您显示嵌套异常(未记录)。甚至有人建议这个 nested_exception typedef 也应该是库的一部分;同时,自己编写也很容易。

但不要指望魔法:boost::current_exception 只有在抛出站点使用 boost::启用_current_exception。 (从功能上讲,这在道德上等同于使用可以克隆的异常基类)。如果没有,它不会失败,但一些信息可能会丢失。


最后要注意的是,C++0x 采用了 Boost.Exception 的设计。因此,以下正确存储事件异常,没有任何 boost::current_exception 警告,因为它具有语言支持:

// you can still use Boost.Exception:
typedef boost::error_info<struct tag_nested_exception, std::exception_ptr>
nested_exception;

// ...
catch(...) {
// e has type std::exception_ptr
auto e = std::current_exception();
// internally store the std::exception_ptr
throw your_exception_type(e);

// or with Boost
BOOST_THROW_EXCEPTION( your_exception_type() << nested_exception(e) );
}

还有一个 std::nested_exception 类型可以很容易地像这样使用:

catch(...) {
// throws an unspecified type derived from your_exception_type
// and std::nested_exception
std::throw_with_nested(your_exception_type());
}

关于c++ - C++ 异常中的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6577513/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com