什么是 std::exception::what() 以及为什么要使用它?

what is std::exception::what() and why to use it?

我来自 c++98,我正在努力进入 c++11 等等。我遇到了 public 成员函数,std::exception::what,<=> virtual const char* what() const noexcept;

从这个例子 givin in 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() 它呢?我可以在我的 class 异常中实现我自己的 tostring 方法并调用它!
  3. 在what()的return值中,见下文,保证至少在...或调用异常对象的非const成员函数之前有效 的含义是什么,或者直到异常对象的非常量成员函数被调用 ,有人可以用示例解释一下吗?

what() return value

A pointer to a c-string with content related to the exception. This is guaranteed to be valid at least until the exception object from which it is obtained is destroyed or until a non-const member function of the exception object is called.

谢谢。

关于您的第一个问题,请查看 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函数或其他函数满足您的需要,请使用它。不要自己发明并尝试调试它。

  1. what is the noexcept at the end?

这是C++11引入的新说明符。简而言之,这意味着该函数不会抛出异常。 noexceptthrow().

含义相同

did it bring something new?

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

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

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

当其他人调用你的功能时同样适用。他们可能不想/或不需要知道您的特殊异常 class,但如果您继承 std::exception.

,他们仍然可以捕获它并打印消息
  1. what is the meaning of or until a non-const member function of the exception object is called

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

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