gcc默认析构函数的异常规范 [英] gcc exception specification of default destructor

查看:354
本文介绍了gcc默认析构函数的异常规范的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

class A
{
    public:
    virtual ~A()
    {
    }
};

class B : virtual public A
{
    public:
    ~B() throw()
    {}
};

class C : public B
{
};

int main(int argc, char * argv [])
{
return 0;
}

该代码给出以下错误:

error: looser throw specifier for ‘virtual C::~C()’
error:   overriding ‘virtual B::~B() throw ()’



)),但是编译没有错误在以前的gcc版本(我的debian系统上的4.5)。

on my debian testing ( gcc (Debian 4.6.0-10) 4.6.1 20110526 (prerelease) ) but compiles without errors on previous gcc versions ( 4.5 on my debian system again).

异常规范如何影响虚拟析构函数覆盖?$
根据答案,编译器应该创建一个与基类的throw声明匹配的默认构造函数。显然这不是什么发生在新的gcc。发生了什么变化,什么是正确的编译器行为,并且除了在派生类中手动添加空析构函数(例如编译器标志)之外,还有一些简单的解决方案。

How does an exception specification affect virtual destructor overriding? According to that answer the compiler is supposed to create a default constructor matching the throw declaration of the base class. Obviously this is not what happens on new gcc. What has changed, what is the correct compiler behavior and is there some easy solution to the problem other than manually adding empty destructors in derived classes ( compiler flag for example).

推荐答案

我假设在实际代码中〜A()〜B $ c>被声明为虚拟? (错误消息是抱怨一个虚拟析构函数,但在代码中写的没有析构函数是虚拟的)

I presume that in the real code either ~A() or ~B() is declared virtual? (The error message is complaining about a virtual destructor, but in the code as written none of the destructors are virtual.)

我相信虚拟继承是什么触发你问题。 C(隐式定义)析构函数需要先调用〜B(),然后,因为C是最派生的类,所以调用〜A ()。 (12.4 / 6)

I believe the virtual inheritance is what is triggering your problem. C's (implicitly defined) destructor is required to first call ~B() and then, because C is the most-derived class, to call ~A(). (12.4/6)

需要生成〜C()的生成异常规范以允许任何异常传播,因为它直接调用没有异常规范的〜A()。 (15.4 / 13)

The generated exception specification for ~C() is required to allow any exception to propagate, because it directly calls ~A() which has no exception specification. (15.4/13)

然后会触发你的错误 - 你不能使用 throw $ c>规范(B的析构函数)与一个可能会抛出的版本。 (15.4 / 3)

And that then triggers your error - you can't override a virtual function with a throw() specification (B's destructor) with a version that may throw. (15.4/3)

解决方案是将 throw()放在A的析构函数上。 (如果你不能这样做,那么为什么你在B上这么做?)

The solution would be to put throw() on A's destructor. (If you can't do that, then why are you doing it on B's?)

错误也不会发生没有虚拟继承 - 因为然后C的析构函数只会调用B的析构函数。 (B的析构函数仍然会调用A的 - 你还在滑冰,因为如果A的析构函数抛出你直接到 terminate()。)

The error also wouldn't happen without the virtual inheritance - because then C's destructor would only call B's destructor. (B's destructor would still call A's - and you're still skating on thin ice, because if A's destructor throws you're going straight to terminate().)

这篇关于gcc默认析构函数的异常规范的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆