【问题标题】:what is std::exception::what() and why to use it?什么是 std::exception::what() 以及为什么要使用它?
【发布时间】:2020-10-25 08:26:27
【问题描述】:

我来自 c++98,我正在尝试进入 c++11 等等。我遇到了公共成员函数,std::exception::whatvirtual const char* what() const noexcept;

从这个例子中给出的 c++ 参考:what_example,我可以理解用法,但我有几个问题:

// exception::what
#include <iostream>       // std::cout
#include <exception>      // std::exception

struct ooops : std::exception {
  const char* what() const noexcept {return "Ooops!\n";}
};

int main () {
  try {
      throw ooops();
  } catch (std::exception& ex) {
      std::cout << ex.what();
  }
  return 0;
}
  1. 在 c++98 中,what() 为:virtual const char* what() const throw();,而在 c++11 中,它变为 virtual const char* what() const noexcept;。最后的noexcept 是什么?有没有带来新的东西?
  2. 我为什么要使用what()呢?我可以在我的类异常中实现我自己的 tostring 方法并调用它!
  3. 在what() 的返回值中,见下文,保证至少在...或直到调用异常对象的非常量成员函数之前有效。 或直到调用异常对象的非常量成员函数是什么意思,有人可以举例解释一下吗?为什么会这样?

what() return value

指向带有异常相关内容的 c 字符串的指针。这是 保证至少在异常对象之前有效 它被销毁或直到一个非常量成员函数 异常对象被调用

谢谢。

【问题讨论】:

  • 请不要同时提出多个问题。尤其是当他们每个人都可以被自己的 SO 帖子覆盖时。第一个是stackoverflow.com/questions/12833241/…的副本
  • @StoryTeller-UnslanderMonica-也许在您附加的链接中他们有部分答案,但这仍然不能回答我的问题。

标签: c++ c++11 exception noexcept


【解决方案1】:
  1. 最后的noexcept 是什么?

它是 C++11 中引入的新说明符。简而言之,就是函数不会抛出异常。 noexceptthrow() 含义相同。

它带来了什么新东西吗?

noexcept 是对旧的 throw 说明符的改进,该说明符已被弃用 (C++11),然后从语言中删除 (C++20)。它接受一个布尔表达式,该表达式确定该函数是 noexcept 还是可能抛出。这在通用模板编程中很有用,因为模板的某些实例可能会抛出,而其他实例可能不会。

  1. 我为什么要使用what()呢?我可以在我的类异常中实现我自己的 tostring 方法并调用它!

因为您可能正在使用不是您编写的函数,因此不会抛出您的异常类。例如,某些标准函数在某些情况下会抛出异常,而所有标准异常都源自std::exception。在这种情况下,访问错误消息的唯一方法是通过what 成员函数。

其他人调用您的函数时也是如此。他们可能不想/或不需要知道您的特殊异常类,但如果您继承 std::exception,他们仍然可以捕获并打印消息。

  1. 异常对象的非 const 成员函数被调用之前或之前是什么意思

意思是字面意思。如果在从std::exception 派生的异常对象上调用what,并存储返回的指针,然后调用该异常对象的非常量成员函数,则存储的指针将无效。

任何通过无效指针间接进行的尝试(例如尝试打印异常消息)都将导致未定义的行为。

【讨论】:

    【解决方案2】:

    对于您的第一个问题,请查看 StoryTeller 的评论。至于第二点:

    why should i use what() it at all? i can emplement my 
    own tostring method in my class exception and call it instead!
    

    编程的第一条规则是不要重新发明轮子,如果 STL 库中有一个 toString 函数或其他满足您需求的函数,请使用它。不要自己发明并尝试调试它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-22
      • 1970-01-01
      • 2021-12-09
      • 2015-09-08
      • 2022-01-22
      • 2011-06-18
      • 1970-01-01
      相关资源
      最近更新 更多