2

为什么std::runtime_error::what()返回const char*而不是std::string const&?在许多情况下,直接返回对嵌入字符串的引用会很方便,并且可以避免一些开销。那么首先不返回例如对内部字符串的 const 引用并且不提供重载函数的理由是什么?我想它与能够抛出异常的字符串 ctor 一起使用,但我看不到返回字符串引用的风险。

4

3 回答 3

5

std::runtime_error继承自std::exceptionwhich 定义virtual const char* what() const throw();,因此最简单的响应是它是函数的重载,并且您可以确定任何标准异常都以这种方式定义它。它可能(取决于实现)可以返回std::string,但它与标准库的其余部分不一致。

what()我认为返回的原因const char*是您可以避免任何可能失败的操作(尤其是可能引发异常的操作)。考虑下面的代码,它不应该失败

virtual const char* what() const throw() {
    return "An error has occured";
}

但是在下面的代码中,分配std::string可能会失败,抛出异常:

std::string what() const throw() {
    return std::string("An error has occured");
}

如果字符串的构造函数扔在这里,应用程序很可能无论如何都会崩溃,因为函数指定throw().

在异常内部使用std::string会引入分配内存的需要,这可能是不可能的(请注意,也std::bad_alloc继承自std::exception)。

于 2012-07-21T17:55:09.587 回答
4

不一定有嵌入式std::string. 成员函数是虚拟的what,即它被设计为被覆盖。覆盖它的主要原因是以其他方式提供字符串,而不是通过使用的机制std::runtime_error(无论该机制是什么,很可能是一个 stored std::string)。

于 2012-07-21T17:44:23.407 回答
1

虽然 runtime_error 确实将 std::string 作为参数,因此它可以保留它并按照您的建议返回它,但 what() 方法是从 std::exception 继承的,因此更通用。

抛出异常的开销可能已经很高了,堆栈展开,所以你不应该担心这一点额外的开销。

于 2012-07-21T17:49:26.913 回答