天天看點

[C++再學習系列] 深入new/delete:Operator new的全局重載

我們經常看到這麼一句話: operator new 可以重載, placement new 不可重載。其實此處所說的不可重載應該是指全局的placement new 不可重載,對于類域中的 placement new 是可以重載的,而且隻要重載了任何一種形式的 operator new 都應該順便重載 placement new , 即 void * operator new(std::size_t count, void *ptr) 。

操作符重載一般用于特定類型,名字解析過程同一般的函數重載。 Operator new 由于其特殊性,編譯器提供了預設提供 6種全局重載形式,同時還允許使用者提供自定義的全局 operator new ,其參數甚至可以和全局版本一樣,除全局 placement new外。對于類域,任何形式的 new 都是可以重載的,包括 placement new 形式。 

void *operator new(std::size_t count) throw(std::bad_alloc);           // 一般的版本 

void *operator new(std::size_t count,   // 相容早版本的 new

    const std::nothrow_t&) throw();       // 記憶體配置設定失敗不會抛出異常

void *operator new(std::size_t count, void *ptr) throw();  //placement 版本

void *operator new[](std::size_t count)  //

    throw(std::bad_alloc);

void *operator new[](std::size_t count,  //

    const std::nothrow_t&) throw();

void *operator new[](std::size_t count, void *ptr) throw();

重載 operator new 的參數個數是可以任意的 , 隻需要保證第一個參數為 size_t, 傳回類型為 void * 即可 , 而且其重載的參數類型也不必包含自定義類型 . 更一般的說 , operator new 的重載更像是一個函數的重載 , 而不是一個操作符的重載 . 如:

全局重載示例:

void* operator new(size_t size)  // 重載成功

{

   printf("global new\n");

   return malloc(size);

   //return ::operator new(size);  // 遞歸調用提示 (warning)

}

//void *operator new(std::size_t size, void *ptr) // 無法重載

//{

//     printf("global new\n");

//     return ::operator new(size,ptr);

//}

void * operator new(size_t size, const std::nothrow_t& e)  // 重載成功 , 遞歸調用提示 (warning)

       printf("global new\n");

       return ::operator new(size, e);

一般形式的 operator new 重載示例:

void * operator new(size_t size, int x, int y, int z){

    ...

X * pX = new (1, 2, 3) X; 

char data[1000][sizeof(foo)];

inline void* operator new(size_t size, int n) {

        return data[n];

就可以使用這樣有趣的文法來建立對象 :

foo *p=new(6) foo();   // 把對象建立在 data 的第六個單元上

---------------------------------------------------

歡迎轉載,請注明作者和出處

本文轉自 zhenjing 部落格園部落格,原文連結: http://www.cnblogs.com/zhenjing/archive/2011/01/13/groble_new.html  ,如需轉載請自行聯系原作者

繼續閱讀