使用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();
}
}
Run Code Online (Sandbox Code Playgroud)
我正在寻找同一主题的例子但是对于C++我找不到任何(也许我没有找到正确的术语,因为你可以看到这个问题的标题不是很花哨).
无论如何,在C++中这样做的正确方法是什么?它是将内部异常存储为指针还是引用?(我想我可能需要一个指针,所以当它是第一个异常时它可以为null).当我引发异常时,它是否应该像创建的指针一样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;
}
Run Code Online (Sandbox Code Playgroud)
Luc*_*ton 21
使用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() );
}
Run Code Online (Sandbox Code Playgroud)
这非常有用,boost::diagnostic_info支持它并将为您显示嵌套异常(它没有记录).甚至有人认为这也nested_exception typedef应该是图书馆的一部分; 与此同时,你自己写的很容易.
不要指望魔术:boost::current_exception'捕获'活动异常(精细打印:或者它的克隆)只有在使用投掷站点时才会很好boost::enable_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) );
}
Run Code Online (Sandbox Code Playgroud)
还有一种std::nested_exception类型可以很容易地使用,如下所示:
catch(...) {
// throws an unspecified type derived from your_exception_type
// and std::nested_exception
std::throw_with_nested(your_exception_type());
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2551 次 |
| 最近记录: |