gpt4 book ai didi

c++ - 覆盖 std :exception 的析构函数

转载 作者:可可西里 更新时间:2023-11-01 16:07:28 27 4
gpt4 key购买 nike

如果 line 8 被注释,则以下程序无法在 g++ 4.4 中编译。为什么?似乎当我重写 std::exception 构造函数时,我也必须重写它的析构函数。这是什么原因?

#include<iostream>
#include<exception>
using namespace std;

class A : public exception {
public:
A(string msg) : _msg(msg) {}
//~A() throw(){}; // line 8
const char* what() const throw() { return _msg.c_str();}
private:
string _msg;
};

int main()
{
}

编译错误为:

error: looser throw specifier for ‘virtual A::~A()’

最佳答案

这是因为析构函数需要一个 throw() 说明符。如果你没有在你的类中指定它,编译器会为你的类编写它自己的默认析构函数,并且默认析构函数不会指定你不抛出异常。

这是正确的,因为 std::exception 的公共(public)析构函数也指定了 throw()

~A() throw(){};

来自标准 (N3225) 12.4.4 :

If a class has no user-declared destructor, a destructor is implicitly declared as >defaulted (8.4). An implicitly- declared destructor is an inline public member of its class.

因此,如果您不自己声明析构函数,编译器会创建下一个析构函数。如果您的所有异常成员析构函数都符合 nothrow 条件,则编译器可能会生成一个指定了 throw() 的析构函数。

~A(){};

从技术上讲,可以从这个析构函数中抛出异常,但那将是非常糟糕的编程风格,因此从 std::exception 派生的异常保证你不会在std::exception 派生类的析构函数。

编辑如果 std::string 的析构函数是 noexcept 指定的,较新的编译器将提供一个具有 noexcept 说明符的析构函数。如果所有成员的析构函数都没有抛出异常(是 noexcept 限定的),其他编译器也会生成一个 noexcept 析构函数。这是 C++11 标准在第 15.4 章中强制要求的。 [除了.spec]

14 An implicitly declared special member function (Clause 12) shall have an exception-specification. If f is an implicitly declared default constructor, copy constructor, move constructor, destructor, copy assignment operator, or move assignment operator, its implicit exception-specification specifies the type-id T if and only if T is allowed by the exception-specification of a function directly invoked by f’s implicit definition; f shall allow all exceptions if any function it directly invokes allows all exceptions, and f shall allow no exceptions if every function it directly invokes allows no exceptions. [...]

关于c++ - 覆盖 std :exception 的析构函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18416780/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com