如果删除析构函数,编译器还会隐式生成默认构造函数吗?

问题描述 投票:0回答:1

如果删除析构函数,编译器还会隐式生成默认构造函数吗? 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++标准的态度呢?也就是说,在语言标准层面,是不允许生成默认构造函数的,但在编译器实现层面,是允许生成默认构造函数的。这是正确的吗?

c++ constructor destructor
1个回答
0
投票

是的,如果用户没有声明其他构造函数,则始终隐式声明默认构造函数。与析构函数无关。

std::is_default_constructible<A>
失败,因为
std::is_(*_)constructible
特征不检查对象是否可以构造。相反,他们检查直接初始化中具有相应类型的变量的定义是否格式良好,即这里是否

A a();

格式良好,但声明不被解释为函数声明。只有当析构函数也可用时,这样的变量定义才是格式良好的。

© www.soinside.com 2019 - 2024. All rights reserved.