1、C++的記憶體配置設定是一種類型操作:new為特定類型配置設定記憶體,并在新配置設定的記憶體中構造該類型的一個對象。new表達式自動運作合适的構造函數來初始化動态配置設定的類類型對象。
2、在每種情況下(預先配置設定記憶體以儲存使用者級(user-level objects)對象或者儲存類的内部資料)都需要将記憶體配置設定與對象構造分離開。
3、對未構造的記憶體中的對象進行指派而不是初始化,其行為是未定義的。對許多類而言,這樣做引起運作時崩潰。
4、C++提供下面兩種方法配置設定和釋放未構造的原始記憶體。
1)allocator 類,它提供可感覺類型(type-aware)的記憶體配置設定。這個類支援一個抽象接口,以配置設定記憶體并随後使用該記憶體儲存對象。
2)标準庫中的 operator new 和 operator delete函數,它們配置設定和釋放需要大小的原始的、未類型化的記憶體。
5、C++ 還提供不同的方法在原始記憶體中構造和撤銷對象。
1)allocator 類定義了名為 construct 和 destroy 的成員:construct 成員在未構造記憶體中初始化對象,destroy 成員在對象上運作适當的析構函數。
2)定位 new 表達式(placement new expression)接受指向未構造記憶體的指針,并在該空間中初始化一個對象或一個數組。
3)可以直接調用對象的析構函數來撤銷對象。運作析構函數并不釋放對象所在的記憶體。
4)算法 uninitialized_fill 和 uninitialized_copy 像 fill 和 copy算法一樣執行,除了它們在目的地構造對象而不是給對象指派之外。
現代 C++ 程式一般應該使用 allocator 類來配置設定記憶體,它更安全更靈活。但是,在構造對象的時候,用 new 表達式比allocator::construct 成員更靈活。有幾種情況下必須使用new。
6、allocator 類
allocator類是一個模闆,它提供類型化的記憶體配置設定以及對象構造與撤銷。
allocator<T> a;
定義名為a的allocator對象,可以配置設定記憶體或構造T類型的對象
a.allocate(n)
配置設定原始的未構造記憶體以儲存 T 類型的 n 個對象
a.deallocate(p, n)
Deallocates memory that held n objects of type T starting at address contained
in the T* pointer named p . It is the user's responsibility to run destroy on
any objects that were constructed in this memory before calling deallocate .
a.construct(p, t)
在 T* 指針 p 所指記憶體中構造一個新元素。運作 T 類型的複制構造函數用 t 初始化該對象
a.destroy(p)
運作 T* 指針 p 所指對象的析構函數
uninitialized_copy(b, e, b2)
從疊代器 b 和 e 指出的輸入範圍将元素複制到從疊代器b2 開始的未構造的原始記憶體(unconstructed, raw memory)中。該函數在目的地構造元素,而不是給它們指派。假定由 b2 指出的目的地足以儲存輸入範圍中元素的副本
uninitialized_fill(b, e, t)
将由疊代器 b 和 e 指出的範圍中的對象初始化為 t 的副本。假定該範圍是未構造的原始記憶體。使用複制構造函數構造對象
uninitialized_fill_n(b, e, t, n)
将由疊代器 b 和 e 指出的範圍中至多 n 個對象初始化為t 的副本。假定範圍至少為n個元素大小。使用複制構造函數構造對象
allocator類将記憶體配置設定和對象構造分開。當allocator對象配置設定記憶體的時候,它配置設定适當大小并進行記憶體對齊(aligned)來儲存給定類型對象的空間。但是,它配置設定的記憶體是未構造的,allocator的使用者必須分别construct和destroy放置在該記憶體中的對象。
1)使用allocator管理類成員資料
示例代碼

7、operator new函數和operator delete函數
// new expression
string * sp = new string("initialized");
的時候,實際上發生三個步驟。首先,該表達式調用名為 operator new 的标準庫函數,配置設定足夠大的原始的未類型化的記憶體,以儲存指定類型的一個對象;接下來,運作該類型的一個構造函數,用指定初始化式構造對象;最後,傳回指向新配置設定并構造的對象的指針。
當使用 delete 表達式
delete sp;
删除動态配置設定對象的時候,發生兩個步驟。首先,對 sp 指向的對象運作适當的析構函數;然後,通過調用名為 operator delete 的标準庫函數釋放該對象所用記憶體。
我們不能重定義new和delete表達式的行為。
1)operator new與operator delete接口
void *operator new(size_t); // allocate an object
void *operator new[](size_t); // allocate an array
void *operator delete(void*); // free an object
void *operator delete[](void*); // free an array
2)使用配置設定操作符函數
雖然 operator new 和 operator delete 函數的設計意圖是供 new 表達式使用,但它們通常是标準庫中的可用函數。可以使用它們獲得未構造記憶體,它們有點類似 allocate 類的 allocator 和 deallocate 成員。
使用示例
注意:使用allocator與operator new有一個重要的差別就是:operator new在void*指針而不是類型化的指針上進行操作。一般而言,使用allocator比直接使用operator new與operator delete函數更為類型安全。
allocate成員配置設定類型化的記憶體,是以使用它的程式可以不必計算以位元組為機關的所需記憶體量,它們也可以避免對 operator new 的傳回值進行強制類型轉換。類似地,deallocate釋放特定類型的記憶體,也不必轉換為void*。
8、定位new表達式
标準庫函數 operator new 和 operator delete 是 allocator 的allocate 和 deallocate 成員的低級版本,它們都配置設定但不初始化記憶體。
There are also lower-level alternatives to the allocator members construct and destroy . Thesemembers initialize and destroy
objects in space allocated by an allocator object.
類似于construct成員,第三種new表達式,稱為定位new(placement new)。定位new表達式在已配置設定的原始記憶體中初始化一個對象,它與new的其他版本的不同在于:它不配置設定記憶體,相反,它接受指向已配置設定但未構造記憶體的指針,并在該記憶體中初始化一個對象。實際上,定位new表達式使我們能夠在特定的、預配置設定的記憶體位址構造一個對象。
new (place_address) type
new (place_address) type (initializer-list)
其中 place_address 必須是一個指針,而 initializer-list 提供了(可能為空的)初始化清單,以便在構造新配置設定的對象時使用。
定位new表達式比allocator類的construct成員更靈活。定位new表達式初始化一個對象的時候,它可以使用任何構造函數,并直接建立對象。construct函數總是使用複制構造函數。