从默认构造函数调用成员的析构函数

Member's destructor calling from default constructor

class Part
{
public:
    ~Part() = delete;
};

class CL
{
public:
    CL(){} //error: deleted destructor call
    ~CL();
    Part part;
};

int main()
{
}

此代码给出了与 Part 的已删除析构函数调用相关的错误。成员析构函数调用的默认构造函数中的上下文是什么?

P.S: 据我所知,Part 成员的析构函数必须在 ~CL() 中调用,但它不是专门为演示而定义的,默认构造函数在任何地方强制它

每个构造函数都需要访问其成员的析构函数。当构造函数抛出异常时,它必须能够销毁在抛出异常之前初始化的每个成员。您可以验证这对每个构造函数都是正确的。如果您尝试向构造函数添加任意参数,错误仍然发生,即使使用复制和移动构造函数。

正如评论中提到的,CL() = default; 不会产生错误。这是因为 CL() = default; 只是导致编译器生成它通常会生成的隐式默认构造函数。在这种情况下,看起来 CL 有一个 deleted implicitly-declared default constructor,这意味着自动生成的隐式默认构造函数将被删除。如果您尝试以下操作,您会发现默认构造函数实际上不可用:

#include <type_traits>

class Part
{
public:
    ~Part() = delete;
};

class CL
{
public:
    CL() = default;
    ~CL();
    Part part;
};

// This assert passes
static_assert(std::is_default_constructible<CL>::value == false, "");

但是,我无法准确解释为什么 CL 有一个已删除的隐式声明的默认构造函数,我也无法解释为什么CL() noexcept {}; 不起作用。

首先,Part 是根据 [special]p5.

CL 可能构造的子对象

For a class, its non-static data members, its non-virtual direct base classes, and, if the class is not abstract, its virtual base classes are called its potentially constructed subobjects.

因此 Part 的析构函数 可能根据 [class.base.init]p12 被调用 ,而不管 nonexcept 是否存在。

In a non-delegating constructor, the destructor for each potentially constructed subobject of class type is potentially invoked.

因此根据 [class.dtor]p12.

,程序格式错误

A program is ill-formed if a destructor that is potentially invoked is deleted or not accessible from the context of the invocation.

请注意,即使删除的析构函数实际上并未被调用,只要析构函数可能被调用,程序就是格式错误的。