【问题标题】:Maybe I'm missunderstanding C++ Exceptions?也许我误解了 C++ 异常?
【发布时间】:2012-11-15 10:15:45
【问题描述】:

我正在努力解决异常问题,我猜想他们能做什么,更重要的是他们应该做什么和不应该做什么。

所以,我将举一个例子来说明我是如何思考一个非常具体的问题的,并希望人们会祝福或抨击我的想法。

我正在从 xml 文件中读取设置,所以我可能有这些设置,但也存在特定设置可能不存在的情况,这会产生一些麻烦和很多“点错误” -handling”或者叫什么,类型: (注意:这不是“真正的代码”,而只是一些伪代码,希望能说明我的观点)。

if (xml.attribute("some_attrib")) {
    settingForSomeAttrib = xml.attribute("some_attrib")->value();
} else {
    settingForSomeAttrib = "some default value";
}

因此,对于我想做的每件事和任何事情,这或多或少都会给我留下支票和分配,这是不可取的。

然后我在想,也许我可以把这一切都处理一遍,取出任何出错的东西并将其交给默认值,稍微试着把它弄好,任何不成功的东西我们都会处理之后..

引导我进入try/catch 类型的思维。

然后我在想也许我可以做一个尝试块:

try {
    setting1 = xml.attribute("attr1")->value(); // throws some kind of "attr1" exception?
    setting2 = xml.attribute("attr2")->value(); // -||-                "attr2" exception?
} catch (???) {
    //go through the things which went wrong and set them settings straight!
}

希望这有某种意义,或者至少可以遵循我的思路。我觉得这并不是真正应该如何使用异常。

我认为我的问题是这样的:

1) 异常可以像这样使用还是只是个坏主意? 2) 人们通常如何在 C++ 中进行此操作,以获取在检查有效性时并不臃肿的代码?

谢谢。

【问题讨论】:

  • 我当然不会使用异常来处理只是可选的设置。
  • 在您的try/catch 示例中,如果settings1 行生成异常,则由于异常,以下所有行都不会执行。因此,您需要在每个属性 get 周围放置一个 try/catch,这与上面的 if/else 相同。我要做的是首先初始化所有内容,然后尝试从 XML 中提取,如果该值不存在,那也没关系。编辑:我也喜欢下面的@NPE 示例。
  • 一般来说,对意外(或者,我敢说,异常)情况使用异常。您应该期望缺少可选属性,因此这不是例外情况。
  • 谢谢,这正是我需要听到的,以及我觉得一切就绪的答案:)
  • Exceptions 应该在特殊情况下使用。线索就在名字里。

标签: c++ xml exception error-handling


【解决方案1】:

我当然不会使用异常来处理仅仅是可选的设置。

相反,我会按照以下方式做一些事情:

string getString(const XML& xml, const string& attrib, const string& defaultAttrib) {
  if (xml.attribute(attrib)) {
    return xml.attribute(attrib)->value();
  } else {
    return defaultAttrib;
  }
}

...
setting1 = getString(xml, "attrib1", "attrib1_default");
... 

【讨论】:

  • default 是一个关键字,不能在 switch 语句之外使用,尽管 VC++ 允许它(可能将其视为上下文关键字)。无论如何,这个解决方案效果很好,因为可以提供没有defaultAttrib 参数的重载,而在else 分支中反而会引发异常。
  • @GManNickG:很好的回复default,谢谢(奇怪的是我把它叫做别的东西,但后来决定将名称缩短为default,以使声明适合代码框。 .. d'oh! :-))
  • 非常有帮助,这确实为我提供了我想要的干净的实现,并且处理了错误,而我最终不会得到臃肿的代码。谢谢你。
【解决方案2】:

我偶尔会看到以这种方式使用异常,但我认为这里没有必要或可取,尤其是因为您似乎必须检查所有各种设置,或手动跟踪你停在哪里。

怎么样

setting1 = attribute_value(xml, "attr1", default1);
setting2 = attribute_value(xml, "attr2", default2); 

attribute_value 包含判断"attr1" 是否存在的逻辑。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多