在effective中meyers提到了怎樣定製一個類得自己的operator new 操作符函數:
代碼類似如下:
[code=C/C++]void * Myclass ::operator new(size_t size)
{
new_handle globalHandle=std::set_new_handle(currentHandle);
void *memory;
try
{
memory=::operator new(size);
}
catch(std::bad_alloc&)
{
std::set_new_handle(globalHandle);
throw;
}
std::set_new_handle(globalHandle);
return memory;
}[/code]
以前我的理解是, 在調用Myclass *pm=new Myclass 的時候,在new操作符內部先調用malloc函數配置記憶體大小,再調用 類Myclass的預設建構函式。那麼我們在對類Mycalss定義自己的operaotr new 操作符的時候,就必須在為它分配等於sizeof(Mycalss)的記憶體空間之後,再調用它的預設建構函式。但是我在meyers的這個自訂的operator new 裡面並沒有看到這個對預設建構函式的調用。於是,我猜想在operator new 內部只是簡單的調用malloc來返回一個void *指標,而這個對預設建構函式的調用是在對operator new 函數結束之後,由編譯器自動進行的,而不是在operaotr new 內部進行的。
結論:當調用語句:Myclass *pm=new Myclass的時候,如果我沒有對calss Myclass 定製我自己的oprator new ,那麼它就會先調用全域的operator new ,編譯器再在這個基礎上面調用它的預設建構函式。當我們的類自己定義了operator new 操作符的時候,它就先調用類自己的new,編譯器再調用它的預設建構函式。而malloc與new的區別就在於:如果是malloc,那麼它簡單返回一個指向分配記憶體的空間的void *指標,如果是new,那麼在返回void *指標之後,編譯器還會調用相應的類的預設建構函式。其中最重要的是:對預設建構函式的調用不是operator new進行的,而是編譯器進行的。
例如:Myclass *pm=new Myclass的時候,它等價於下面的偽c++代碼:
void *pm=Myclass::operator::new(sizeof(Myclass));
Myclass::Myclass(pm);