使用运算符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。
使编译器生成的默认构造函数和用户定义的默认构造函数之间发生什么区别?
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
。