c++新内存替换和作用域解析

C++ new - memory substitution and scope resolution

本文关键字:替换 作用域解析 内存 新内存 c++      更新时间:2023-10-16

我在看下面的代码:

// 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));
    

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

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

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

Answer1:当您为新对象重用它的内存时,位于p2的对象的生命周期结束。它不会运行析构函数,所以它不会被干净地"销毁",尽管只有POD成员而没有用户声明的析构函数,但在这种情况下,这没有什么区别。

Answer2:使用::强制查找operator new只考虑在全局作用域声明的operator new。在您调用operator new的作用域中,在任何情况下都不会考虑其他operator new,因此没有区别。