如果删除析构函数,编译器还会隐式生成默认构造函数吗? 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++标准的态度呢?也就是说,在语言标准层面,是不允许生成默认构造函数的,但在编译器实现层面,是允许生成默认构造函数的。这是正确的吗?
是的,如果用户没有声明其他构造函数,则始终隐式声明默认构造函数。与析构函数无关。
std::is_default_constructible<A>
失败,因为std::is_(*_)constructible
特征不仅检查对象是否可以构造。相反,他们检查直接初始化中具有相应类型的变量的定义是否格式良好,即这里是否
A a();
格式良好,但声明不被解释为函数声明。只有当析构函数也可用时,这样的变量定义才是格式良好的。