异常类中的Setter

时间:2010-11-08 16:59:48

标签: c++

在异常类中使用setter成员函数会有什么影响? 拥有一个setter的动机是,有时候在投掷点没有足够的数据可用于在捕获点正确处理异常;因此,当堆栈被解开时,必须添加附加信息。

4 个答案:

答案 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如何实现异常处理(直到汇编程序级别),并且这个想法没有任何问题。应该提到一些要点:

  1. 在展开堆栈后,调用<{1}}块。因此,相应的catch块中的所有内容都已已经已被销毁。
  2. 重新抛出异常会导致性能受到重大影响。

答案 3 :(得分:1)

我认为潜在的问题是抛出(低级别)代码没有代码进一步增加的上下文/信息。

您可以创建一个更好地描述异常的新异常,将原始异常包装为内部异常。我已经做了几次,但我发现这在所有情况下都不实用。

我知道有些框架有一个“数据”属性,它或多或少是一个包含任意数据的字典。这对我来说听起来并不坏,尽管它会被滥用。它可能不应该用于制定程序化决策,它应该用于人类消费。

如果有东西捕获异常,并根据参数X做出决定,那么它可能会变得非常混乱。