从默认构造函数调用成员的析构函数
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.
请注意,即使删除的析构函数实际上并未被调用,只要析构函数可能被调用,程序就是格式错误的。
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.
请注意,即使删除的析构函数实际上并未被调用,只要析构函数可能被调用,程序就是格式错误的。