为什么只有在声明自定义构造函数时才能访问基类析构函数? [英] Why must a base class destructor be accessible only when a custom constructor is declared?

查看:205
本文介绍了为什么只有在声明自定义构造函数时才能访问基类析构函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Comeau,g ++( ideone )和EDG接受以下代码,无需诊断。 Visual C ++编译成功,但警告C4624。

Comeau, g++ (ideone) and EDG accept the following code without diagnostic. Visual C++ compiles successfully, albeit with warning C4624.

class indestructible_base
{
  ~indestructible_base();
};

class T : indestructible_base
{
public:
  //T() {}
};

int main(void) { new T(); }

取消注释构造函数,它不再编译。

Uncomment the constructor and it no longer compiles.

也许这是规则,如果一个异常发生在构造函数内,子对象必须被销毁?看起来很奇怪,因为正文是空的,不能引起异常。即使这样,添加一个异常规范凭证,不会抛出任何异常( throw() noexcept )和它没有什么区别。

Perhaps it's the rule that if an exception occurs inside the constructor, subobjects must be destroyed? Seems odd, since the body is empty and can't cause an exception. Even so, add an exception-specification vouching for the fact that no exception will be thrown (throw() or noexcept) and it makes no difference.

为什么用户声明的构造函数需要访问基类析构函数,而自动生成的构造函数不会?

Why does a user-declared constructor require access to the base class destructor, while an automatically-generated constructor does not?

此问题的灵感来自:阻止析构函数在C ++中运行


This question was inspired by: Preventing a Destructor from Running in C++

推荐答案

我怀疑这可能是编译器特定的行为。这是我的理论:

I suspect that this might be compiler-specific behavior. Here's my theory:

因为(在这种特殊情况下)隐式定义的T()是一个平凡的构造函数5)),编译器甚至不会尝试生成T()的主体。因为没有ctor体,所以没有任何异常可能会在构造(其中没有任何真正的)时产生,因此不需要生成dtor调用,因此不需要生成dtor体,只是为了发现基类的dtor是私有的。

Because (in this particular case) an implicitly-defined T() is a trivial constructor (as defined in 12.1(5) of the standard), the compiler doesn't even attempt to generate a body for T(). Since there's no ctor body, there are no exceptions that could possibly be generated during "construction" (of which there isn't any, really), so there's no need to generate a dtor call, and so no need to generate a dtor body, only to find out that the base class's dtor is private.

但是一旦T()变得不平凡(即使它保持隐式定义) ctor主体必须生成,并得到错误。只要向类T中添加一个具有用户定义构造函数的成员,就会使隐式定义的T()变得不重要。

But as soon as T() becomes non-trivial (even if it remains implicitly-defined), a ctor body must be generated, and you get the error. Something as simple as adding a member to class T that has a user-defined constructor would make the implicitly-defined T() become non-trivial.

相关,问题是新的T()不生成dtor调用(因为你没有对应的 delete 任何地方)。相反,如果我只是在代码中替换 new T() T dummy ,那么我得到以下 gcc ,表明它现在正在对dtor辅助功能进行完全检查(因为必须生成dtor调用):

A separate, but related, issue is that new T() doesn't generate a dtor call (since you don't have a corresponding delete anywhere). In contrast, if I just replace new T() with T dummy in your code, then I get the following from gcc, suggesting that it's now doing the full check for dtor accessibility (as a consequence of having to generate a dtor call):

test.cpp: In destructor 'T::~T()':
test.cpp:3: error: 'indestructible_base::~indestructible_base()' is private
test.cpp:7: error: within this context
test.cpp: In function 'int main()':
test.cpp:12: note: synthesized method 'T::~T()' first required here
test.cpp:12: warning: unused variable 'dummy'

这篇关于为什么只有在声明自定义构造函数时才能访问基类析构函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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