有人可以解释这篇MS文本试图传达的内容吗?

时间:2011-12-13 20:31:03

标签: c++

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个参数

1 个答案:

答案 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;
};

如果 功能不存在,则根本不会调用任何函数。因此,如果您不得不负责清理资源(例如移动池指针或更新空闲列表),则不会发生这种情况。