我只能想到以下使用std :: exception :: what()的情况:
输出它,例如MessageBox(e.what())
或cout << e.what()
。据我所知,这些消息对许多用户来说都是无用的。例如,当我尝试重命名不存在的文件时:
boost::filesystem::rename: 系统找不到指定的文件。: "D:\MyDesktop\4", "D:\MyDesktop\5"
(中文单词的意思是“系统找不到指定的文件。”)用户如何解密混合的东西?此外,它是const char*
而不是像const platform_char*
这样的东西,在Windows中可能会出现unicode问题。
std::regex_match(e.what()...)
。我认为显示设计缺陷是一个可怕的想法。那么我应该在哪里使用std :: exception :: what()?它没用吗?
答案 0 :(得分:4)
程序员应该从std::exception
和taylor what()
派生出一个类来满足特定要求。然后它可以非常有用。
报告某些内容也很有用(例如,以纯文本形式记录日志),这就是为什么标准要求具体的std::exception::what()
而不是纯虚函数。
答案 1 :(得分:4)
what()
在某种意义上是通用的,它意味着您希望它对您自己的异常类意味着什么。在许多情况下,它仅用于记录,但在其他情况下,它可能提供可用于从异常情况中恢复的信息。
答案 2 :(得分:2)
那么我应该在哪里使用std :: exception :: what()?它没用吗?
std :: exception的错误消息是char *,因为它应该是一个尽可能简单的面向用户的诊断消息,提供有关错误的详细信息。
对于boost :: system_error(和std :: system_error),您还可以获取操作系统级别的错误代码(用户友好的消息是“找不到文件”)。
有效用途:
如果要识别错误类型,请捕获专门化std :: system_error或boost :: system_error并在switch/if
函数上执行code()
(即不运行正则表达式在消息上。)
如果要显示诊断(日志记录)或用户友好性(到控制台/ GUI)的错误说明,只需显示错误消息(what()
)。
std :: exception是一个基类(即它有一个虚析构函数)。如果您实现自己的异常类,请遵循与std :: system_error相同的模式:使用错误代码轻松识别错误,并创建异常的基类(通常是std :: exception,std :: runtime_error或std :: logic_error) )根据错误类型使用短信。
最终,错误消息的类型是char *而不是std :: string,wstring或your-platform-specific-char-type,因为它牺牲了可靠性的灵活性:使用char *每个人都知道如何使用它,它没有编码(ASCII除外),它是空终止的,一旦分配,它不会失败(它不会产生新的异常)。
在构造异常时使用可能失败的东西(以任何方式)将是灾难性的:在创建/使用错误处理代码的诊断消息时会失败。
这意味着您可以不抛出异常(并且您的应用程序将保持无效状态),或者在创建异常实例时抛出异常(您实际上不希望这样做,因为它会丢弃您想要的异常抛出(隐藏错误)或抛出错误代码丢失或损坏的异常(这可能会浪费几个月的开发时间来追踪错误的错误)。
考虑这个例子(不必要的复杂,但它提出了一个观点):
int * p = new(nothrow) int(10); // I want to throw a complicated
// string message exception
if(nullptr == p)
throw complicated_exception(std::string("error message here"));
抛出线可能会失败:应用程序的内存很少,甚至不会分配int *,更不用说字符串了。这段代码的结果是在低内存条件下我仍然会得到一个std :: out_of_memory错误 - 一个由std :: string构造函数生成的错误。
std :: exception是一个很好的实现:它提供了一个最小的可扩展接口,具有良好的故障点管理/限制,并为扩展提供了良好的接口(例如std :: system_error)。