int *pi = new int(5);但事實上它是由以下兩個步驟完成:
// 調用函數庫中的new運算符 int *pi = __new(sizeof(int));2.給配置得來的對象設立初值:
*pi = 5;更進一步地,初始化操作應該在內存配置成功(經由 new 運算符)後才執行:
// new運算符的兩個分離步驟 // given: int *pi = new int(5); // 重寫聲明 int *pi; if (pi = __new(sizeof(int))) *pi = 5;delete 運算符的情況類似,當程序員寫下:
delete pi;時,如果pi的值是0,C++語言會要求 delete 運算符不要有操作.因此,編譯器必須為此調用構造一層保護膜:
if (pi != 0) __delete(pi);請注意pi並不會因此被自動清除為0,因此像這樣的後繼行為:
// 沒有良好的定義,但是合法 if (pi && *pi == 5) ...雖然沒有良好的定義,但是可能(也可能不)被評估為真.這是因為對於pi所指向的內存的變更或再使用,可能(也可能不)會發生.
// pi仍然指向合法空間 // 甚至即使儲存於其中的object已經不再合法 if (pi == sentine1) ...在這裡,使用指針pi和使用pi所指的對象,其差別在於哪一個的聲明已經結束了.雖然該地址上的對象不再合法,但地址本身卻仍然代表一個合法的程序空間.因此pi能夠繼續被使用,但只能在受限制的情況下,很像一個 void * 指針的情況.
Point3d *origin = new Point3d;被轉換為:
Point3d *origin; if (origin = __new(sizeof(Point3d))) origin = Point3d::Point3d(origin);如果exception handling的情況下,destructor應該被放在一個try區段中.exception handler會調用 delete 運算符,然後再一次丟出該exception.
extern void *operator new(size_t size) { if (size == 0) size = 1; void *last_alloc; while (!(last_alloc = malloc(size))) { if (_new_handler) (*_new_handler)(); else return 0; } return last_alloc; }雖然這樣寫是合法的:
new T[0];但是語言要求每一次對 new 的調用都必須傳回一個獨一無二的指針.解決該問題的傳統方法是傳回一個指針,指向一個默認為1 byte的內存區塊(這就是為什麼程序代碼中的size被設為1的原因).這個實現技術的另一個有趣之處是,它允許使用者提供一個屬於自己的_new_handler()函數.這正是為什麼每一次循環都調用_new_handler()的緣故.
extern void operator delete(void *ptr) { if (ptr) free((char *)ptr); }
int *p_array = new int[5];時,vec_new()不會真正被調用,因為它的主要功能是把default constructor施行於 class objects所組成的數組的每一個元素上.倒是 new 運算符函數會被調用:
int *p_array = (int *)__new(5 * sizeof(int));相同的情況,如果寫:
// struct simple_aggr {float f1, f2; };
simple_aggr *p_aggr = new simple_aggr[5];vec_new()也不會被調用.為什麼呢?因為simple_aggr並沒有定義一個constructor或destructor,所以配置數組以及清除p_aggr數組的操作,只是單純地獲得內存和釋放內存而已.這些操作由 new 和 delete 運算符來完成就綽綽有余了.
Point3d *p_array = new Point3d[10];通常會被編譯為:
Point3d *p_array;
p_array = vec_new(0, sizeof(Point3d), 10, &Point3d::Point3d, &Point3d::~Point3d);在個別的數組元素構造過程中,如果發生exception,destructor就胡被傳遞給vec_new().只有已經構造妥當的元素才需要destructor的施行,因為它們的內存已經被配置出來了,vec_new()有責任在exception發生的時候把那些內存釋放掉.
delete []p_array;尋找數組維度給 delete 運算符的效率帶來極大的影響,所以才導致這樣的妥協:只有在中括號出現時,編譯器才尋找數組的維度,否則它便假設只有單獨一個object要被刪除.如果程序員沒有提供必須的中括號,像這樣:
delete p_array;那麼就只有第一個元素會被解構,其他元素仍然存在.