就象malloc一樣,operator new的職責(zé)只是分配內(nèi)存。它對構(gòu)造函數(shù)一無所知。operator new所了解的是內(nèi)存分配。把operator new 返回的未經(jīng)處理的指針傳遞給一個對象是new操作符的工作。當(dāng)你的編譯器遇見這樣的語句:
string *ps = new string("Memory Management"); 它生成的代碼或多或少與下面的代碼相似(更多的細(xì)節(jié)見Effective C++條款8和條款10,還有我的文章Counting object里的注釋。):
有時你確實(shí)想直接調(diào)用構(gòu)造函數(shù)。在一個已存在的對象上調(diào)用構(gòu)造函數(shù)是沒有意義的,因為構(gòu)造函數(shù)用來初始化對象,而一個對象僅僅能在給它初值時被初始化一次。但是有時你有一些已經(jīng)被分配但是尚未處理的的(raw)內(nèi)存,你需要在這些內(nèi)存中構(gòu)造一個對象。你可以使用一個非凡的operator new ,它被稱為placement new。
下面的例子是placement new如何使用,考慮一下:
class Widget { public: Widget(int widgetSize); ... };
Widget * constrUCtWidgetInBuffer(void *buffer,
int widgetSize) { return new (buffer) Widget(widgetSize); } 這個函數(shù)返回一個指針,指向一個Widget對象,對象在轉(zhuǎn)遞給函數(shù)的buffer里分配。當(dāng)程序使用共享內(nèi)存或memory-mapped I/O時這個函數(shù)可能有用,因為在這樣程序里對象必須被放置在一個確定地址上或一塊被例程分配的內(nèi)存里。(參見條款4,一個如何使用placement new的一個不同例子。)
string *ps = new string[10]; // allocate an array of // objects 被使用的new仍然是new操作符,但是建立數(shù)組時new操作符的行為與單個對象建立有少許不同。第一是內(nèi)存不再用operator new分配,代替以等同的數(shù)組分配函數(shù),叫做operator new[](經(jīng)常被稱為array new)。它與operator new一樣能被重載。這就答應(yīng)你控制數(shù)組的內(nèi)存分配,就象你能控制單個對象內(nèi)存分配一樣(但是有一些限制性說明,參見Effective C++ 條款8)。
new和delete操作符是內(nèi)置的,其行為不受你的控制,凡是它們調(diào)用的內(nèi)存分配和釋放函數(shù)則可以控制。當(dāng)你想定制new和delete操作符的行為時,請記住你不能真的做到這一點(diǎn)。你只能改變它們?yōu)橥瓿伤鼈兊墓δ芩扇〉姆椒ǎ鼈兯瓿傻墓δ軇t被語言固定下來,不能改變。(You can modify how they do what they do, but what they do is fixed by the language)