2

我正在查看以下代码:

// operator new example
#include <iostream>     // std::cout
#include <new>          // ::operator new

struct MyClass {
  int data[100];
  int kk;
  MyClass(int ea) : kk(ea) {std::cout << "constructed [" << this << "]\n";}
};

int main () {

  std::cout << "1: ";
  MyClass * p1 = new MyClass(1);
      // allocates memory by calling: operator new (sizeof(MyClass))
      // and then constructs an object at the newly allocated space

  std::cout << "2: ";
  MyClass * p2 = new (std::nothrow) MyClass(2);
      // allocates memory by calling: operator new (sizeof(MyClass),std::nothrow)
      // and then constructs an object at the newly allocated space

  std::cout << "3: ";
  new (p2) MyClass(3);
      // does not allocate memory -- calls: operator new (sizeof(MyClass),p2)
      // but constructs an object at p2

  // Notice though that calling this function directly does not construct an object:
  std::cout << "4: ";
  MyClass * p3 = (MyClass*) ::operator new (sizeof(MyClass));
      // allocates memory by calling: operator new (sizeof(MyClass))
      // but does not call MyClass's constructor

  delete p1;
  delete p2;
  delete p3;

  return 0;
}

我有两个问题:

  • 执行该行时对象2是否被破坏

    new (p2) MyClass(3);
    

那应该在对象 2 的分配空间中构造对象 3 吗?

  • 线

    MyClass * p3 = (MyClass*) ::operator new (sizeof(MyClass));
    

没有 :: 也可以工作,在没有类/命名空间的情况下使用范围解析运算符的目的是什么?

4

2 回答 2

3

首先,不,第二个对象的析构函数没有被调用。一个新对象只是在它的位置初始化。如果您愿意,可以p2->~MyClass();在重用内存之前显式调用对象的析构函数。

其次,使用 using::来限定分配函数的目的是确保它来自全局命名空间。该标准为所有翻译单元隐式定义了两个重载operator new,如果包含<new>,则会得到一些额外的。所有这些都定义在全局命名空间中(不在 中std)。可以重载operator new类(只需将它们作为成员函数提供),因此限定 with::确保使用全局版本。

于 2013-04-14T16:46:14.647 回答
2

p2答案 1:当您将其内存用于新对象时,位于的生命周期中的对象将结束。它不会运行其析构函数,因此它不会被干净地“销毁”,尽管只有 POD 成员并且没有用户声明的析构函数,在这种情况下它没有区别。

答案 2:使用::强制查找operator new仅考虑operator new在全局范围内声明。在您调用的范围内,在任何情况下都不会考虑operator new其他operator new任何情况,因此没有区别。

于 2013-04-14T16:47:23.767 回答