c++ 什么是std::exception::what()?为什么要使用它?

ffscu2ro  于 2023-02-10  发布在  其他
关注(0)|答案(3)|浏览(510)

我是从c 98开始的,我正在努力学习c11等等。我遇到了公共成员函数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;
}

1.在c 98中,what()是:virtual const char* what() const throw();,在c11中,它变成了virtual const char* what() const noexcept;,最后的noexcept是什么?它带来了什么新的东西吗?
1.我为什么要使用what()呢?我可以在我的类异常中实现我自己的tostring方法并调用它!
1.在what()的返回值中,见下文,保证至少有效到...或直到异常对象的非常数成员函数被调用或直到异常对象的非常数成员函数被调用是什么意思,有人能用例子解释一下吗?为什么?
what() return value
一个指向包含异常相关内容的C字符串的指针。它保证至少在异常对象被销毁或异常对象的非常数成员函数被调用之前有效。
谢谢。

g2ieeal7

g2ieeal71#

1.最后的noexcept是什么?
它是C11中引入的一个新的说明符。简而言之,它意味着函数不会抛出异常。noexceptthrow()的含义相同。
有什么新的发现吗
noexcept是对旧的throw说明符的改进,后者已被弃用(C
11),然后从语言中删除(C++20)。它接受一个布尔表达式,该表达式确定函数是noexcept还是可能抛出。这在泛型模板编程中很有用,因为模板的某些示例可能抛出,而其他示例可能不会。
1.我为什么要使用what()it呢?我可以在类异常中实现我自己的tostring方法,然后调用它!
因为您可能正在使用不是您编写的函数,因此不会抛出异常类。例如,某些标准函数在某些情况下会抛出异常,而所有标准异常都是从std::exception派生的。在这种情况下,访问错误消息的唯一方法是通过what成员函数。
当其他人调用你的函数时也是如此,他们可能不想或不需要知道你的特殊异常类,但是如果你继承了std::exception,他们仍然可以捕获它并打印消息。
1.在调用异常对象的非常数成员函数之前,或的含义是什么
如果你在一个从std::exception派生的异常对象上调用what,并存储返回的指针,然后调用该异常对象的一个非常数成员函数,那么存储的指针将是无效的。
任何试图通过无效指针进行间接访问的行为(例如试图打印异常消息)都将导致未定义的行为。

lo8azlld

lo8azlld2#

你的第一个问题可以看看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函数或其他函数满足您的需要,就使用它。不要发明自己的函数并试图调试它。

8ulbf1ek

8ulbf1ek3#

作为第三个问题的补充:
有时候,人们会惊讶地发现,车轮没有被重新发明是多么重要;共享同一个基类可能是件大事。
因此,当程序由于抛出异常而崩溃时,会出现一个std::cerr消息,显示what的内容。

相关问题