筆者覺得這3個new有點意思,有時候我也被搞懵了,這些創造者難不成覺得C++過于簡單,所以搞一點含糊的術語出來。這次總結一下,以便再懵的時候有個參考。有錯的地方請不吝賜教,多謝先!
簡單點吧:
1. new operator,即熟悉的new操作符,用它從堆中分配一個對象,并且初始化。CHeapObject* p=new CHeapObject(name);
既然是操作符,那么它的行為就和其他+-*/操作符一樣,是由C++語言定義的,不能改變,即使通過重載的方式也不能改變。C++規定了new操作符的行為:分配一個合適的空間容納CHeapObject對象,然后調用其構造函數初始化對象。
2. operator new,就是new操作,1種說的“分配一個合適的空間容納CHeapObject對象”就是通過new操作完成的。全局的new操作是如下聲明的:
void * operator new(size_t size);
這是一個函數聲明,在C++里我們可以通過重載該函數改變這個函數的行為,即分配空間的方式,相信大家都干過這事。
補充一下,雖然operator new是給new operator調用的,但是也可以被你調用,如:
void* p=operator new(sizeof(CHeapObject));
它只分配空間,等同于C里的malloc()。
雖然我們重載了operator new,但是我們沒有改變1中new operator的行為。
3. placement new
唉,我又懵了:-)
這是在已經分配好的空間上(比如malloc, operatornew,返回的void*,沒有對象信息),調用CHeapObject的對象構造函數,這也是一個特殊的new操作。上例子吧:
void* buffer=operator new(100*sizeof(CHeapObject));///分配100個對象的空間
CHeapObject* construct(void* buf, string objname)
{
return new(buf) CHeapObject(objname);
}
這個函數返回對象指針,對象是在傳遞進來的buffer上分配。這個new的用法是new操作符的另一個用法,需要一個額外的變量buf,new操作的隱含調用operator new的時候會把buf傳遞給它,這是operator new的定義如下:
void * operator new(size_t, void *buffer)
{
return buffer;
}
這就是placement new。
最后來個總結吧:
如果想在堆上創建一個對象,應該用new操作符,它分配內存,同時又為對象調用構造函數。
如果僅僅想分配內存,就用operator new函數,它不會調用構造函數。
如果你想定制自己的在堆對象被建立時的內存分配過程,應該重載寫你自己的operator new函數,new操作符會調用你定制的operator new。
如果想在一塊已經分配好的內存里建立一個對象,使用placement new。