operator new() 在删除 operator delete() 时的行为不同,具体取决于默认构造函数的存在

operator new() behaves differently when operator delete() is deleted depending on the existence of the default constructor

使用 operator new() 创建 class C 的新对象在此处出现错误:

class C
{
public:
    C() {}
    virtual ~C() {}

    void operator delete(void*) = delete;
};


int main()
{
    C* c = new C;
}

C2280: 'void C::operator delete(void *)': function was explicitly deleted

但是当我替换 C() {} C() = default; 或删除该行,以便编译器插入一个默认构造函数(我相信它与 = default 具有相同的效果),代码将编译并 运行.

编译器生成的默认构造函数和用户定义的默认构造函数之间有什么不同?

我在 this posting 中得到了一些提示,但是 class 这里的 C(没有用户提供的构造函数)并不简单,因为析构函数是虚拟的,对吗?

使用最新 Visual Studio、c++17.

编译

What are the differences between compiler-generated default constructor and user-defined default constructor that make this happen?

new 表达式调用相应的 operator new 然后调用构造函数。如果构造函数抛出异常 new 表达式必须通过调用相应的 operator delete 来撤消 operator new 的效果(以避免内存泄漏)。如果删除后者 new 表达式将无法调用它,这会导致编译器 error: use of deleted function 'static void C::operator delete(void*)'.

A noexcept 构造函数不可能抛出异常,因此,相应的 operator delete 不是必需的,因为它不会被 new 表达式调用。普通 class 的 default 构造函数也是 noexcept 构造函数。虚拟析构函数的存在要求 operator delete 不被删除,因为特殊的 标量删除析构函数 (通过基数 [= 启用 delete 表达式的实现细节41=] 指针) 调用 operator delete.

C++ 标准似乎没有指定编译器是否必须要求 operator delete 不被删除,即使它不可能被 new 表达式调用。 gcc,但是,如果它是 deleted(发布了 bug report),似乎根本不会调用 new 表达式中相应的 operator delete