对于定位New,是指预先分配一个空间,然后再在这个空间中分配对象。
特点:
在预定空间分配的对象和这个空间在同一个地址上。
注意点:
1、无论在这个空间生成多少个对象,其地址都一样,就是这个空间的地址。
2、书中说
// 检查一个对象是否被放在buf 中
if ( pb->val() == 0 )
我觉得这是不对,就算buf
只有一个空间,也能生成对象。所以只要生成了对象,这个判断都是真。
我认为应该是:
if(pb == buf)//???
这样对么?
3、对于生成的对象必须手动析构,不然将无法释放对应的(如在构造函数中生成了对象,但是如果没有调用析构函数则会内存泄露):
pb->~Foo();
这些书上并没有说明。
这种空间申请与对象初始化分离的做法是很有用的.比如实现对象内存池时,就可以用到,可以先在堆里申请一大块的内存空间,这空间只是纯粹的空间,当使用时就提取出来分配给各个不同的对象,然后再由各个独立的对象再自行初始化就行了,回收时在各个类里得先自行显式地调用析构函数(如果是POD<plain
old
data>类型的空间就省去这一步,STL的内存池就是这样做的),再把空间还给内存池,这样子就可以达到空间的重用性
每次调用 new (buf) ...都是返回相同的内存地址,所以如何解析上面的问题?
也就是如:
A * pA = new (buf) A;
B* pB = new (buf + sizeof(A)) B;
这样理解对么?
不过如果这样,释放后再重新利用将比较复杂?
日常开发中有用到过么?
当内存块从内存池摘走给一个客户端后,若再从内存池取相同大小的内存块时,内存池也就不会将前面已摘走的内存块给当前请求的客户端.当回收时,内存池只需简单地将相同大小的内存块放入在相同的串列就可以了,这样子就可以省去频繁向系统申请堆空间的开销,同时也能兼顾到各个不同类对内存空间的初始化
当内存块从内存池摘走给一个客户端后,若再从内存池取相同大小的内存块时,内存池也就不会将前面已摘走的内存块给当前请求的客户端.当回收时,内存池只需简单地将相同大小的内存块放入在相同的串列就可以了,这样子就可以省去频繁向系统申请堆空间的开销,同时也能兼顾到各个不同类对内存空间的初始化