在异常类中使用setter成员函数会有什么影响? 拥有一个setter的动机是,有时候在投掷点没有足够的数据可用于在捕获点正确处理异常;因此,当堆栈被解开时,必须添加附加信息。
答案 0 :(得分:5)
在标题为将任意数据添加到活动异常对象的段落中查看Boost.Exception库并最准确地this page:
void parse_file( char const * file_name )
{
boost::shared_ptr<FILE> f = file_open(file_name,"rb");
assert(f);
try
{
char buf[1024];
file_read( f.get(), buf, sizeof(buf) );
}
catch(boost::exception & e )
{
e << boost::errinfo_file_name(file_name);
throw;
}
}
我个人认为技术非常有效。修改异常(添加上下文)并重新抛出。
与Java相反,在C ++中,您决定在构建异常时是否包含堆栈帧,因此您不会冒失去它的风险,它仍然会引用抛出该异常的代码点。第一个例外,虽然有重要的背景。
答案 1 :(得分:3)
虽然你可以解释原始异常,但我更喜欢Java中使用的技术:你捕获原始文件并抛出一个新的异常,引用原始异常作为其原因。
答案 2 :(得分:1)
首先,这听起来不错。
我使用SEH(特定于Windows的异常处理,与C ++无关)而不是C ++异常处理。特别是因为它 - 它允许在堆栈展开开始之前收集更多信息。
但我从来没有想过会抛出一种会“收集”信息的类型。
从技术上讲 - 没有问题。我知道MSVC如何实现异常处理(直到汇编程序级别),并且这个想法没有任何问题。应该提到一些要点:
catch
块中的所有内容都已已经已被销毁。答案 3 :(得分:1)
我认为潜在的问题是抛出(低级别)代码没有代码进一步增加的上下文/信息。
您可以创建一个更好地描述异常的新异常,将原始异常包装为内部异常。我已经做了几次,但我发现这在所有情况下都不实用。
我知道有些框架有一个“数据”属性,它或多或少是一个包含任意数据的字典。这对我来说听起来并不坏,尽管它会被滥用。它可能不应该用于制定程序化决策,它应该用于人类消费。
如果有东西捕获异常,并根据参数X做出决定,那么它可能会变得非常混乱。