1、对象可能被覆盖。Placement new的工作机理是提供一个缓冲区来装东西,这个东西可是任何东西,但是在这里我说的是对象。如果你没有特别指定偏移量那么对象是从缓冲区的起始处开始存储的。如果你有n个对象需要存储并且也没有指定偏移量,那么前n-1个对象会被第n个对象覆盖,就算不覆盖也会有区域重叠,而那个重叠区域最后的数据属于第n个对象。所以你在同一个缓冲区存储多个对象的时候一定要指定偏移量。例如下图:
Pc3就加上了偏移量这样第二个对象就不会覆盖第一个对象了。
2、如果出现了覆盖的情况,被覆盖的对象将不会自动调用析构函数。不调用析构函数会怎样?就会造成资源泄露呗!那么事实是否果真如此,让我们做个实验,如下图所示:
这个base的源码如下所示:
由上图可知这个析构函数如果正常工作的话会打印两个~base
works语句,由此可见单单是把placement
new的缓冲区delete掉是不会自动调用析构函数的。
那应该如何解决这一问题?答案就是你显式地调用它们的析构函数。
如下图所示:
结果如下所示:
这样就能够达到调用析构函数的目的。
在这里我感觉应该解决一个额外的问题,那就是地址0019A018-0019A010=8,那为什么p2-p1等于4而不是等于8呢?那是因为你所看到每一个十六进制数字都是由4bit组成的,所以它们之间加减运算也是以4bit为单位的,即它们相减的结果是8个4bit=32bit=4byte。所以简化一下计算过程就是(p2-p1)*4/8=(p2-p1)/2就OK了。