MoreEffectiveC++:理解new和delete

字號:

人們有時好像喜歡故意使C++語言的術語難以理解。比如說new操作符(new operator)和operator new的區(qū)別。
    當你寫這樣的代碼:
    string *ps = new string("Memory Management");
    你使用的new是new操作符。這個操作符就象sizeof一樣是語言內(nèi)置的,你不能改變它的含義,它的功能總是一樣的。它要完成的功能分成兩部分。第一部分是分配足夠的內(nèi)存以便容納所需類型的對象。第二部分是它調(diào)用構造函數(shù)初始化內(nèi)存中的對象。new操作符總是做這兩件事情,你不能以任何方式改變它的行為。
    你所能改變的是如何為對象分配內(nèi)存。new操作符調(diào)用一個函數(shù)來完成必需的內(nèi)存分配,你能夠重寫或重載這個函數(shù)來改變它的行為。new操作符為分配內(nèi)存所調(diào)用函數(shù)的名字是operator new。
    函數(shù)operator new 通常這樣聲明:
    void * operator new(size_t size);
    返回值類型是void*,因為這個函數(shù)返回一個未經(jīng)處理(raw)的指針,未初始化的內(nèi)存。(如果你喜歡,你能寫一種operator new函數(shù),在返回一個指針之前能夠初始化內(nèi)存以存儲一些數(shù)值,但是一般不這么做。)參數(shù)size_t確定分配多少內(nèi)存。你能增加額外的參數(shù)重載函數(shù)operator new,但是第一個參數(shù)類型必須是size_t。(有關operator new更多的信息參見Effective C++ 條款8至條款10。)
    你一般不會直接調(diào)用operator new,但是一旦這么做,你可以象調(diào)用其它函數(shù)一樣調(diào)用它:
    void *rawMemory = operator new(sizeof(string));
    操作符operator new將返回一個指針,指向一塊足夠容納一個string類型對象的內(nèi)存。
    就象malloc一樣,operator new的職責只是分配內(nèi)存。它對構造函數(shù)一無所知。operator new所了解的是內(nèi)存分配。把operator new 返回的未經(jīng)處理的指針傳遞給一個對象是new操作符的工作。當你的編譯器遇見這樣的語句:
    string *ps = new string("Memory Management");
    它生成的代碼或多或少與下面的代碼相似(更多的細節(jié)見Effective C++條款8和條款10,還有我的文章Counting object里的注釋。):
    void *memory = // 得到未經(jīng)處理的內(nèi)存
    operator new(sizeof(string)); // 為String對象
    call string::string("Memory Management") //初始化
    on *memory; // 內(nèi)存中
    // 的對象
    string *ps = // 是ps指針指向
    static_cast(memory); // 新的對象
    注意第二步包含了構造函數(shù)的調(diào)用,你做為一個程序員被禁止這樣去做。你的編譯器則沒有這個約束,它可以做它想做的一切。因此如果你想建立一個堆對象就必須用new操作符,不能直接調(diào)用構造函數(shù)來初始化對象。