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

nor*_*nor -1 c++ exception noexcept c++11

我来自 c++98,我正在尝试进入 c++11 等等。我遇到了公共成员函数 , std::exception::what, <=>virtual 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;
}
Run Code Online (Sandbox Code Playgroud)
  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 字符串的指针。这保证至少在从中获取它的异常对象被销毁或者直到异常对象的非常量成员函数被调用之前是有效的。

谢谢。

eer*_*ika 5

  1. noexcept最后是什么?

它是 C++11 中引入的新说明符。简而言之,这意味着该函数不会抛出异常。noexcept与 具有相同的含义throw()

它带来了新的东西吗?

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

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

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

当其他人调用您的函数时同样适用。他们可能不想/或不需要了解您的特殊异常类,但如果您继承,他们仍然可以捕获它并打印消息std::exception

  1. 或直到异常对象的非常量成员函数被调用是什么意思

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

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