如果删除了析构函数,编译器是否仍隐式生成默认构造函数?
下面的代码可以通过GCC编译:
struct A
{
~A() = delete;
int x;
int y;
virtual void foo()
{
}
};
int main()
{
A *pmc = new A; // Allowed by the compiler GCC, but causes memory leak
return 0;
}
字符串
这表明GCC认为它可以在这种情况下隐式生成一个默认构造函数。默认构造函数的汇编代码也可以在Godbolt上查看:
A::A() [base object constructor]:
push rbp
mov rbp, rsp
mov QWORD PTR [rbp-8], rdi
mov edx, OFFSET FLAT:vtable for A+16
mov rax, QWORD PTR [rbp-8]
mov QWORD PTR [rax], rdx
nop
pop rbp
ret
型
然而,当用类型特征进行检验时,答案是否定的:
cout << is_default_constructible<A>::value; // false
型
那么,is_default_constructible
是否代表了C++标准的态度呢?也就是说,在语言标准层面,不允许生成缺省构造函数,但在编译器实现层面,允许生成缺省构造函数。
是这样吗?
1条答案
按热度按时间sbtkgmzw1#
是的(对于标题中的问题),如果没有其他构造函数是用户声明的,则默认构造函数总是隐式声明的,尽管如果子对象不能被默认初始化或析构,则可以将其定义为删除。类本身的析构函数无关紧要:
如果类
X
没有用户声明的构造函数,则没有参数的非显式构造函数将隐式声明为默认值(dcl.fct.def(https://eel.is/c++draft/dcl.fct.def))。std::is_default_constructible<A>
失败,因为std::is_(*_)constructible
trait并不 * 只 * 检查对象是否可以构造,而是检查直接初始化中具有相应类型的变量的定义是否是良构的,即这里是否字符串
将是格式良好的,除非声明不被解释为函数声明。这样的变量定义只有在析构函数也可用时才是格式良好的。
也就是说,在语言标准级别,不允许生成默认构造函数,但在编译器实现级别,允许生成默认构造函数,这是正确的吗?
不,这个问题开始就没有任何意义。如果标准规定构造函数不是隐式声明/定义的,那么符合标准的编译器就不可能以另一种方式来做。