什么是 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;
}
- 在 c++98 中,what() 是:
virtual const char* what() const throw();
,在 c++11 中,它变为 virtual const char* what() const noexcept;
。最后的 noexcept
是什么?有没有带来新东西?
- 我为什么要使用
what()
它呢?我可以在我的 class 异常中实现我自己的 tostring
方法并调用它!
- 在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函数或其他函数满足您的需要,请使用它。不要自己发明并尝试调试它。
- what is the
noexcept
at the end?
这是C++11引入的新说明符。简而言之,这意味着该函数不会抛出异常。 noexcept
与 throw()
.
含义相同
did it bring something new?
noexcept
是对旧的 throw
说明符的改进,后者已被弃用 (C++11),然后从语言中删除 (C++20)。它接受一个布尔表达式,该表达式确定该函数是 noexcept 还是潜在的抛出。这在通用模板编程中很有用,因为模板的某些实例可能会抛出异常,而其他实例可能不会。
- 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
.
,他们仍然可以捕获它并打印消息
- what is the meaning of or until a non-const member function of the exception object is called
意思是字面意思。如果您在派生自 std::exception
的异常对象上调用 what
并存储返回的指针,然后调用该异常对象的非常量成员函数,则存储的指针将无效。
任何通过无效指针进行间接访问的尝试(例如尝试打印异常消息)都将导致未定义的行为。
我来自 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;
}
- 在 c++98 中,what() 是:
virtual const char* what() const throw();
,在 c++11 中,它变为virtual const char* what() const noexcept;
。最后的noexcept
是什么?有没有带来新东西? - 我为什么要使用
what()
它呢?我可以在我的 class 异常中实现我自己的tostring
方法并调用它! - 在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函数或其他函数满足您的需要,请使用它。不要自己发明并尝试调试它。
- what is the
noexcept
at the end?
这是C++11引入的新说明符。简而言之,这意味着该函数不会抛出异常。 noexcept
与 throw()
.
did it bring something new?
noexcept
是对旧的 throw
说明符的改进,后者已被弃用 (C++11),然后从语言中删除 (C++20)。它接受一个布尔表达式,该表达式确定该函数是 noexcept 还是潜在的抛出。这在通用模板编程中很有用,因为模板的某些实例可能会抛出异常,而其他实例可能不会。
- 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
.
- what is the meaning of or until a non-const member function of the exception object is called
意思是字面意思。如果您在派生自 std::exception
的异常对象上调用 what
并存储返回的指针,然后调用该异常对象的非常量成员函数,则存储的指针将无效。
任何通过无效指针进行间接访问的尝试(例如尝试打印异常消息)都将导致未定义的行为。