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
,但是,如果它是 delete
d(发布了 bug report),似乎根本不会调用 new
表达式中相应的 operator delete
。
使用 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
,但是,如果它是 delete
d(发布了 bug report),似乎根本不会调用 new
表达式中相应的 operator delete
。