当 operator delete() 被删除时,operator new() 的行为取决于默认构造函数的存在

yes*_*jho 16 c++ default-constructor delete-operator

使用运算符 new() 创建类 C 的新对象会在此处出现错误:

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

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


int main()
{
    C* c = new C;
}
Run Code Online (Sandbox Code Playgroud)

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

但是,当我更换C() {} 使用C() = default; 或删除线,使编译器插入一个默认的构造函数(我相信有同样的效果= default),该代码将编译并运行。

使这种情况发生的编译器生成的默认构造函数和用户定义的默认构造函数之间有什么区别?

我在这篇文章中得到了一些提示,但是这里的 C 类(没有用户提供的构造函数)并不是微不足道的,因为析构函数是虚拟的,对吧?

使用最新的 Visual Studio,c++17 编译。

Max*_*kin 16

使这种情况发生的编译器生成的默认构造函数和用户定义的默认构造函数之间有什么区别?

new表达式调用相应的operator new然后调用构造函数。如果构造函数抛出异常new表达式,则必须operator new通过调用相应的operator delete. 如果后者被删除,则new表达式无法调用它,从而导致编译器error: use of deleted function 'static void C::operator delete(void*)'.

noexcept构造不可能抛出异常,因此,对应的operator delete是没有必要的,因为它不会被称为new表达。一个default微不足道的类的构造函数也是一个noexcept构造函数。虚拟析构函数的存在需要operator delete不被删除,因为特殊的标量删除析构函数delete通过基类指针启用表达式的实现细节)调用operator delete.

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