有人可以向我解释一下C ++中标准异常的定义:
virtual const char* what() const throw();
const throw()
最终意味着什么?
答案 0 :(得分:9)
这是两个独立的,无关的东西。
const
表示成员函数不会修改任何(非mutable
)成员变量;这反过来意味着它可以在const
个对象上调用。 e.g:
class Foo {
public:
void a() const {
x = 5; // Compiler error!
}
void b() {
x = 5; // This is fine
}
private:
int x;
};
int main() {
Foo p;
const Foo q;
p.a(); // This is fine
p.b(); // This is fine
q.a(); // This is fine
q.b(); // Compiler error!
}
throw()
是异常说明符。它声明此函数不会抛出异常。参见例如Should I use an exception specifier in C++?进行讨论。
答案 1 :(得分:6)
const
表示该函数不会更改它所嵌入的类的任何成员,throw()
是一个异常规范;该函数承诺不会抛出异常。
请注意,由于C ++ 11,异常规范throw
由于以下几个原因而被弃用:异常列表在throw(...)
非表达时难以维护,因此{{1}基本上是唯一使用的规范,这些规范在运行时动态检查,产生大量开销,从而减慢了应用程序的速度。
现在,您可以安全地将throw()
替换为throw()
,或仅noexcept(true)
。不会检查这样的方法是否实际抛出异常 - 这是对编译器的保证,反之亦然。如果抛出异常,则调用noexcept
。
答案 2 :(得分:2)
这些是不同的问题。
const
从标准(如果太长,只读粗体部分):
非静态成员函数
[...]非静态成员函数可以声明为const,volatile或const volatile。这些cv限定符 影响this指针的类型(9.3.2)。它们还影响成员函数的函数类型(8.3.5); 一个成员函数声明const是一个const成员函数,一个成员函数声明volatile是 一个volatile成员函数和一个声明为const的成员函数volatile是一个const volatile成员 功能。 [...]
this
指针[...]在const成员函数中,通过const访问访问调用该函数的对象 路径;因此, const成员函数不得修改对象及其非静态数据成员。 [...]
存储类说明符
[...]类数据成员上的mutable说明符使应用于包含类对象的const说明符无效 并且允许修改可变类成员,即使该对象的其余部分是const(7.1.6.1)。
摘要:不允许使用const
限定的成员函数更改任何未声明为mutable
的成员。 mutable
的原因是,即使对象是const
,也可以进行缓存等机制;优良作法是通过调用const成员函数来改变对象的可观察行为。
throw()
例外规范[expect.spec]
函数声明列出了函数可能使用的函数直接或间接抛出的异常 exception-specification作为其声明符的后缀。
更具体地说,它是动态异常规范和
如果函数的动态异常规范包含类型T,则说[...]函数允许类型E的异常 对于类型E的异常,T类型的处理程序将匹配(15.3)。
换句话说,(
和)
中的类型是此函数可能抛出的异常。但是,通常的做法是不使用非空动态异常规范for some good reasons。
使用throw()
,即一个空的例外列表,在预C ++ 11中被接受的做法是注释从不抛出的函数。但是,从C ++ 11(当前标准)开始,应该使用noexcept
代替。
此外,从C ++ 11开始,
[注意:不推荐使用动态异常规范(见附录D)。 - 后注]
所以请改用noexcept
。