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

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

使用运算符new()创建类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中得到了一些提示,但是这里的C类(没有用户提供的构造函数)并不简单,因为析构函数是虚拟的,对吧?

与最新的Visual Studio一起编译,c ++ 17。

c++ delete-operator default-constructor
1个回答
4
投票

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

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构造函数。

[C ++标准似乎未指定编译器是否必须要求不删除operator delete,即使new表达式不可能调用它也是如此。如果gcc标记为operator delete(张贴在new上),则似乎根本不会调用delete表达式中的相应bug report

虚拟析构函数的存在要求不删除operator delete,因为特殊的标量删除析构函数

实现细节将调用operator delete
© www.soinside.com 2019 - 2024. All rights reserved.