C++异常定义

C++ exception definition

本文关键字:定义 异常 C++      更新时间:2023-10-16

谁能向我解释一下标准例外的定义C++:

virtual const char* what() const throw();

最后const throw()是什么意思?

这是两个独立的、不相关的东西。

const意味着成员函数不会修改任何(非mutable(成员变量;这反过来意味着它可以在const对象上调用。 例如:

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()是一个异常说明符。 它声明此函数不会引发异常。 例如,请参阅我应该在C++中使用异常说明符吗?进行讨论。

const 表示该函数不会更改其嵌入的类的任何成员,throw()是一个异常规范;该函数承诺不会抛出异常。

请注意,自 C++11 以来,异常规范 throw 被弃用,原因如下:异常列表太难维护,而throw(...)是非表达性的,因此throw()基本上是唯一使用的规范,并且这些规范在运行时动态检查,产生大量开销,从而减慢应用程序的速度。

现在,您可以安全地将throw()替换为 noexcept(true) ,或者只是noexcept 。不会检查这样的方法是否真的抛出异常 - 这是你给编译器的保证,反之亦然。如果引发异常,则调用std::terminate

这些都是单独的问题。


关于const

从标准(如果太长,只阅读粗体部分(:

非静态成员函数

[...]非静态成员函数可以声明为常量、易失性或常量易失性。这些简历限定符 影响此指针的类型 (9.3.2(。它们还会影响成员函数的函数类型 (8.3.5(; 声明 const 的成员函数是 const 成员函数,声明为 volatile 的成员函数是 易失性成员函数和声明为常量易失性的成员函数是常量易失性成员 功能。[...]

this指针

[...]在 const 成员函数中,调用该函数的对象是通过 const 访问来访问的 路径;因此,const 成员函数不得修改对象及其非静态数据成员。

存储类说明符

[...]类数据成员上的可变说明符使应用于包含类对象的 const 说明符无效 并允许修改可变类成员,即使对象的其余部分是 const (7.1.6.1(。

摘要:不允许使用 const 限定的成员函数更改任何未声明mutable的成员。mutable的原因是,即使一个对象是const的,也可以完成缓存等机制;最好通过调用 const 成员函数来更改对象的可观察行为。


关于throw()

异常规范 [期望规范]

函数

声明列出了其函数可能通过使用 异常规范作为其声明符的后缀。

更具体地说,它是一个动态异常规范,并且

[...]函数被称为允许类型E的异常,如果其动态异常规范包含类型T用于 对于类型 E 的异常,T 类型的处理程序将是匹配项 (15.3(。

换句话说,() 中的类型是此函数可能引发的异常。但是,出于某些充分的理由,通常的做法是不使用非空的动态异常规范。

在 C++11 之前使用 throw(),即空的异常列表是公认的做法来注释永远不会抛出的函数。但是,从当前标准 C++11 开始,应该改用noexcept

此外,截至 C++11,

[ 注:不推荐使用动态例外规范(见附件 D(。

所以改用noexcept