此document包含以下文字和代码:
如果使用new运算符的placement new形式,除了分配大小之外还带有参数的表单,如果构造函数抛出异常,则编译器不支持delete运算符的放置形式。例如:
// expre_new_Operator2.cpp
// C2660 expected
class A {
public:
A(int) { throw "Fail!"; }
};
void F(void) {
try {
// heap memory pointed to by pa1 will be deallocated
// by calling ::operator delete(void*).
A* pa1 = new A(10);
} catch (...) {
}
try {
// This will call ::operator new(size_t, char*, int).
// When A::A(int) does a throw, we should call
// ::operator delete(void*, char*, int) to deallocate
// the memory pointed to by pa2. Since
// ::operator delete(void*, char*, int) has not been implemented,
// memory will be leaked when the deallocation cannot occur.
A* pa2 = new(__FILE__, __LINE__) A(20);
} catch (...) {
}
}
int main() {
A a;
}
如上面第二条评论中所述,代码会发出
C2660:'operator new':没有重载函数需要3个参数
答案 0 :(得分:1)
结果是您必须在匹配对中实现operator new()
和operator delete()
的自定义版本。这可能起初看起来没必要,因为没有“放置 - 删除表达式”:破坏放置新构造对象的唯一方法是通过手动调用析构函数:
A * p = new (addr, true, BLUE) A(1, 'a', x);
// uses void * A::operator new(std::size_t, void *, bool, EnumColour) to
// allocate, then invokes constructor A::A(int, char, X) with "this = p".
// ... it's almost over ...
p->~A(); // now it's over!
当你看到这个时,你会注意到没有假设的“delete (addr, true, BLUE) p
”。那你为什么需要实施void A::operator delete(void *, bool, EnumColour)
?答案正是您引用的文本所描述的情况:当对象的构造函数抛出异常时,编译器会自动尝试调用匹配删除函数:< / p>
struct A {
A(int, char, X) { throw std::runtime_error("Boo!"); }
// ...
static void operator delete(void *, bool, EnumColour) noexcept;
};
如果 功能不存在,则根本不会调用任何函数。因此,如果您不得不负责清理资源(例如移动池指针或更新空闲列表),则不会发生这种情况。