放置C++中的新功能

Cur*_*is2 4 c++

在阅读C++ Primer Plus时,我几乎没有关于新位置的问题.

书中的示例代码如下:

class JustTesting{
private:
  string words;
  int number;
public:
  JustTesting(const string & s = "Just Testing", int n = 0){
    number = n;
    words = s;
    //some code here
  }

  ~JustingTesting(){}
};


char * buffer = new char[BUF];   //get a block of memory
JustTesting *pc1, *pc2;

pc1 = new (buffer) JustTesting;  //Place object in buffer
pc2 = new JustTesting("Heap1",20); //Place object on heap

//some code

JustTesting *pc3, *pc4;

pc3 = new (buffer) JustTesting("Bad Idea", 6);
pc4 = new JustTesting("Heap2", 10);

//some code

delete pc2;   //free Heap1
delete pc4;   //free Heap2

pc3->~JustTesting():   //Does the order of these two destructor call
pc1->~JustTesting();   // matters?

delete[] buffer;       //free buffer
Run Code Online (Sandbox Code Playgroud)

作者说,我们不能使用

delete pc1;
Run Code Online (Sandbox Code Playgroud)

要么

delete pc3;
Run Code Online (Sandbox Code Playgroud)

删除他们指向的对象,因为删除与new一起使用但不与placement new一起使用.例如,指针pc3不接收new返回的地址,delete pc3并将导致运行时错误.

问题是:首先,pc3指向的对象是否会覆盖pc1指向的对象?如果不是,两个不同的对象如何保持在同一个地址中.如果是,为什么我们仍然可以调用析构函数explicit(pc1->~JustTesting();)来释放对象的内存.

问题二:这两个显式析构函数的顺序是否有问题?

问题三:"指针pc3没有收到新的返回地址"是什么意思?新的不同地址是否由赋值给出的地址返回?

谢谢!

344*_*442 5

一切都是对的,直到......

pc3 = new (buffer) JustTesting("Bad Idea", 6);
Run Code Online (Sandbox Code Playgroud)

这会调用未定义的行为(不?).你已经构建了一个类型JustTesting为的对象buffer,但你还没有破坏它!与此同时,要创建在同一地点的另一个对象.然后,第一个对象被破坏(虽然,在标准思想中,它仍然存在于一个平行的宇宙中).

您不能delete对指向尚未分配(和构造)的任何内容执行指针operator new.同样,您只能销毁和取消分配由operator new[]with 创建的数组operator delete[].

现在,"placement new"只是一个直接调用构造函数的奇特名称.因此,new(buff) Type(...)只是Type使用thisset as 调用s构造函数buff.并且,与上述内容相似,您只能破坏已构建的内容.

如果您使用自动存储,operator new或任何其他隐式RAII一致的方法,负责自动分配,构造和破坏您的对象(或指定它应该完成),然后在这样的上下文中调用对象的析构函数将导致析构函数被调用两次,也就是未定义的行为.

现在,碰巧(我会再重复一次吗?你!)是决定何时以及如何获取对象内存的人,然后环境没有改变猜测何时销毁或取消分配对象.因此,一旦你明确地调用了对象的析构函数,曾经包含它的内存由你负责释放,不管怎样,如果有的话.

可以这样想.表单的表达ptr = new X(...)可以完美地实现为......

ptr = malloc(sizeof(X));
new(ptr) X(...);
Run Code Online (Sandbox Code Playgroud)

operator delete变得......

ptr->~X();
free(ptr);
Run Code Online (Sandbox Code Playgroud)