C++内存分配与对象构造的分离(二)
of(T) * newCapacity));
上面两条语句是等价的,下面这两条语句也是等价的。
?
? ? alloc.deallocate(elements, end - elements); ? ? ? ? ? ? ? ?//撤销原内存空间
? ? operator delete[](elements);
说明:allocator类分配类型化的内存,使用时不必计算以字节为单位所需的内存,也避免对operator new的返回值进行强制类型转换。比直接使用operator new,operator delete更为安全。
?
?
?
二、对象构造和撤销
?
C++提供了不同方法在原始内存中构造和撤销对象:
?
(1)allocator类的成员construct和destroy。
?
(2)定位new表达式。
?
(3)直接调用对象的析构函数撤销对象。撤销对象并不释放对象所在的内存。
?
(4)算法uninitialized_copy和uninitialized_fill构造对象。
?
?
?
下面主要介绍定位new表达式(其他情况我们都见过了)。
?
定位new表达式在已分配的原始内存中初始化一个对象,它不分配内存,接受指向已分配但未构造内存的指针,并在该内存中初始化一个对象。定位new表达式的形式是:
?
new (place_address) type
?
new (place_address) type(initializer-list)
?
其中place_address必须为指针,initializer-list提供了一个可能为空的初始化列表。举例如下:
?
alloc.construct(first_free, t);
new (first_free) T(t);
?
string *sp = alloc.allocate(2);
new (sp) string(b, e);
注意:
?
(1)定位new表达式初始化一个对象时,可使用任何构造函数,并直接建立对象。allocator类的construct成员总是使用拷贝构造函数。
?
(2)对于值类型而言,直接构造对象与构造临时对象并进行拷贝没有什么区别,性能差别基本没什么意义。但对某些类而言,使用拷贝构造函数是不可能的(拷贝构造函数可能是私有的等),或应该避免的。这种情况,或许你应该考虑定位new表达式。