繁体   English   中英

std :: exception :: what()的目的是什么?

[英]What is the purpose of std::exception::what()?

我只能想到以下使用std :: exception :: what()的情况:

  1. 用于调试目的。 在我的Visual Studio中,要查看e.what(),我必须将其手动添加到监视列表。 拥有成员std :: string更好吗(调试器直接在对象检查器中显示它),并且仅将其包括在非NDEBUG构建中? 至少他们应该禁用NDEBUG构建中的what()。
  2. 输出它,例如MessageBox(e.what())cout << e.what() 据我所知,这些消息对许多用户都没有用。 例如,当我尝试重命名一个不存在的文件时:

    boost::filesystem::rename: 系统找不到指定的文件。: "D:\\MyDesktop\\4", "D:\\MyDesktop\\5"

    (中文意思是“系统找不到指定的文件。”)用户如何解密混合的内容? 另外,它是const char*而不是const platform_char*类的东西,在Windows中可能会出现unicode问题。

  3. 从中提取数据,例如std::regex_match(e.what()...) 我认为这是一个可怕的想法,显示出设计缺陷。

所以我应该在哪里使用std :: exception :: what()? 它没用吗?

程序员应该从std::exception派生一个类,并根据特定需求选择what() 然后它会非常有用。

这也是有用的报告后面的东西 (如以纯文本的日志记录),这就是为什么标准规定一个具体std::exception::what()而不是一个纯虚函数。

what()是通用的,即它意味着您想要它对自己的异常类意味着什么。 在许多情况下,它仅用于记录日志,但在其他情况下,它可能提供可用于从特殊情况中恢复的信息。

所以我应该在哪里使用std :: exception :: what()? 它没用吗?

std :: exception的错误消息是char *,因为它应该是一种尽可能简单的面向用户的诊断消息,其中提供有关错误的详细信息。

对于boost :: system_error(和std :: system_error),您还可以获得操作系统级别的错误代码(其用户友好消息为“找不到文件”)。

有效用途:

  • 如果要确定错误类型,请捕获专业化std :: system_error或boost :: system_error并在code()函数上执行switch/if (即,而不是在消息上运行正则表达式)。

  • 如果要显示诊断错误(日志记录)或用户友好性(对控制台/ GUI)的说明,只需显示错误消息( what() )。

  • std :: exception是基类(即,它具有虚拟析构函数)。 如果实现自己的异常类,请遵循与std :: system_error相同的模式:使用错误代码轻松识别错误,并创建异常的基类(通常为std :: exception,std :: runtime_error或std :: logic_error ),并根据错误类型显示一条短信。

  • 最终,错误消息的类型是char *而不是std :: string,wstring或您的平台特定的char-type,因为它牺牲了可靠性的灵活性:使用char *,每个人都知道如何使用它,它具有没有编码(ASCII除外),它以null终止,并且一旦分配,就不会失败(不会生成新的异常)。

在构造异常时使用可能会(以任何方式失败)的操作将是灾难性的:您将在创建/使用错误处理代码的诊断消息时失败。

这意味着您要么不能抛出异常(应用程序将保持无效状态),要么在创建异常实例时抛出异常(您实际上不希望那样,因为它会丢弃您要抛出的异常(隐藏)错误)或抛出错误代码缺失或损坏的异常(这可能会浪费多个项目的开发时间来查找错误的错误)。

考虑以下示例(不必要地复杂,但是很重要):

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)提供了良好的接口。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM