C++异常处理准则

C++ Exception Handling Guidelines

本文关键字:异常处理 C++      更新时间:2023-10-16

我正在阅读这个文档 错误处理 在提升网站上。在第五点中,我发现了这个建议。

块引用 "不要太担心what()消息。很高兴有一条程序员有机会弄清楚的消息,但是在引发异常时,您不太可能编写相关且用户可理解的错误消息。当然,国际化超出了异常类作者的范围。Peter Dimod提出了一个很好的论点,即what()字符串的正确使用是作为错误消息格式化程序表的键。现在,如果我们能为标准库抛出的异常获得标准化的 what() 字符串......"

我想知道如何实现这一点(以与语言无关的方式),但我没有那么有经验..你能举一些例子吗?

谢谢!

正如经常发生的那样,"这取决于":-)

我发现what()方法在为高级用户编写的命令行应用程序中非常有用(我开发科学软件)。在这里,国际化不是问题,因为每个人都懂英语,并且在大多数情况下,确实可以提供对用户有意义的错误消息。

我经常使用的另一种方法是"错误类"。此类的实例在主应用程序运行时"收集"错误消息和警告,并且仅在退出时打印已收集的内容。它看起来像这样(只显示了骨架来说明原理):

class Errors {
  public:
  void add_error(const std::string& errmsg);
  void add_warning(const std::string& warnmsg);
  // print all errors and warnings
  void print(std::ostream& out) const;
  // no errors, no warnings
  bool perfect() const { return (_errs.size() + _warns.size()) == 0; }
  // no errors, maybe some warnings
  bool ok() const { return _errs.size() == 0; }
  // ...
  private:
  std::vector<std::string> _errs, _warns;
};

what()的输出可以直接保存在Errors对象中:

try {
  // ...
} catch (const std::exception& ex) {
  errors.add_error(ex.what());
  // ...
}

或者,您可以通过翻译 what() 的输出或使用封装必要信息的复杂异常对象,在 catch 块中生成非常好的错误消息,可能是国际化的。然后在程序结束时,您可以通过调用 print() 方法为用户提供错误的完整列表。

最后,如果您为"非专家用户"编写软件,那么上述其他人指出的所有警告都适用。基本上,应该显示国际化的、易于理解的错误消息,并且尽可能少。可以这么说,您应该"隐藏"例外。没有人喜欢弹出窗口说"错误 #x7582764 发生,正在退出":-)

错误报告的问题很复杂。 对提升站点主要与库代码相关;没有真正标准的国际化处理方式,对于示例,因此您无法在库级别(除非库采用一种特定方式处理它,你通常不想要)。 第二个点更笼统。 甚至忽略国际化,如果例外存在于库代码中,极不可能您可以创建对用户有意义的消息。在这种情况下,你能做的最好的事情就是传递足够的信息以便应用程序可以捕获错误并生成在它正在做的事情的背景下,这是一个有意义的信息。 因此而不是像"no entry 'xyz' in table"这样的东西,你可能会想要输出"Unknown type 'xyz' when deserializing data in file 'abc'".