提问人:AeroSun 提问时间:2/2/2018 最后编辑:milbrandtAeroSun 更新时间:3/17/2022 访问量:1908
如何正确使用BOOST_THROW_EXCEPTION?
How to use BOOST_THROW_EXCEPTION correctly?
问:
我尝试使用提升异常并下降。 有问题代码:
struct exception_base : virtual std::exception, virtual boost::exception
{
exception_base(std::exception&& e)
: std::exception(e)
{}
};
int main()
{
std::string exception_description;
try
{
BOOST_THROW_EXCEPTION(exception_base(std::runtime_error("hello exception")));
}
catch (exception_base& ex)
{
exception_description = boost::diagnostic_information(ex);
}
return 0;
}
在这种情况下,exception_description的值具有最后一个字符串 - “std::exception::what: Unknown exception”。这是意想不到的价值。如果我将BOOST_THROW_EXCEPTION更改为通常的抛出 - exception_description值的最后一个字符串看起来是预期的 - “std::exception::what: hello exception"
那么如何正确使用BOOST_THROW_EXCEPTION呢?
答:
2赞
John Zwinck
2/2/2018
#1
自定义异常类不是必需的,并且是问题的根本原因。如果你删除它,你可以这样做:
BOOST_THROW_EXCEPTION(std::runtime_error("hello exception"));
然后:
catch (const std::exception& ex)
代码将按照您期望的方式工作。
为什么它以前不起作用?好吧,你的类没有存储错误消息,所以当你从 a 构造它时,它不能存储消息(例如,从 原始 )。exception_base
std::exception
runtime_error
你可以用很多不同的方法修复它,但最终它们会归结为同一件事:如果你希望你的自定义异常类包含一个消息字符串,它必须以某种方式包含该消息字符串。
我喜欢在 95% 的时间内不定义自定义异常类型,所以我建议您保持简单并使用(和/或)。runtime_error
logic_error
请注意,它会自动添加为抛出类型的基类,因此您无论如何都不需要自己这样做 - 没有任何优势。BOOST_THROW_EXCEPTION
boost::exception
其他事项:
- 在您的捕获站点使用,这将打印所有添加的元数据,例如:文件、行、函数等
std::cerr << boost::diagnostic_information(ex) << std::endl;
BOOST_THROW_EXCEPTION
- 如果你抛出一个内部,你可以将你的 替换为 将类型更改为 ,这允许您通过
std::exception
BOOST_THROW_EXCEPTION()
std::exception
boost::enable_error_info()
boost::exception
operator<<
评论
0赞
AeroSun
2/2/2018
嗨,约翰,你不明白我的意思。这是描述麻烦的最简单的代码。我需要额外的提升异常未来作为行号、函数名称、出现异常的文件名。因此,我需要按照boost文档中描述的方式使用类exception_base。此外,对于升价期货,我需要使用BOOST_THROW_EXCEPTION而不是普通抛出关键字。
0赞
John Zwinck
2/2/2018
如果你尝试我建议的代码,你会发现它确实支持抛出异常的行号、函数名和文件名。所有这些都是由 自动完成的。试试吧!BOOST_THROW_EXCEPTION
0赞
AeroSun
2/2/2018
我明白了。您的代码只需要一些修复 - catch 中必须有 boost::exception 而不是 std::exception。使用 std::exception 它不适用于我这边,但使用 boost 它可以工作。但!如果我需要自定义例外 - 我能做什么?
0赞
AeroSun
2/2/2018
我也不明白你关于“类没有错误消息存储”的观点 - 为什么?它派生自 std::exception - 因此它具有 std::exception 的所有功能
0赞
John Zwinck
2/2/2018
如果你绝对必须有一个自定义的异常类,那么你需要正确地实现它,将消息存储在里面。为此,你可以从类中派生或在类中添加一个,并将消息存储在该类中。 它里面没有错误消息 - 你可以通过观察它没有接受字符串的构造函数来知道这一点。runtime_error
std::string
std::exception
评论