如果讓我們過載乙個new操作符號,那麼正統的過載方式為:
void * operator new(unsigned int usize)
(1)
也許你已經發現了,有的時候,new的形式遠比這個複雜,比如mfc(在debug版)下的new就是這麼個模樣:
void * operator new(unsigned int usize, const char * szfilename, int nline)
(2)
當然,它這樣的定義,絲毫不會你使用這樣的方式使用new:
int * p = new int[4];
那麼,我使用這樣的形式,它是怎麼呼叫到(2)的呢?
聰明的你或許已經發現了,在你的檔案中發現了這麼一串巨集:
#ifdef _debug
#define new debug_new
#undef this_file
static char this_file = __file__;
#endif
hoho,看到沒?你的new被替換成了debug_new了。(奇怪麼?怎麼連關鍵字都能被define成別的東東呢?別奇怪,你甚至可以#define while for,看看你的程式會怎麼樣?如果這麼幹,然後給別人看看,試試效果:)
繼續跟蹤,看看debug_new的定義:
#define debug_new new(this_file, __line__)
那麼我們還原到我們原始的使用方式裡,它實際是這樣的:
int * p = new(__file__, __line__) int[4];
最後它到operator new函式裡就成了:
int * p = operator new(sizeof(int)*4, __file__, __line__);
奇怪吧,呵呵,它就是這樣的;
也就是說,你可以自己過載寫乙個new,只要保證第乙個引數是關於型別的size,那麼後面的引數可以隨便給的;所以mfc就利用了這一點,將new過載為(2)的形式,這樣,他們就可以得到每個new呼叫的檔名以及所在原始檔中的行數,然後全部記錄下來,這樣當delete的時候可以檢查所有原來申請的記憶體,只要有沒有被釋放的記憶體指標(也就是造成了記憶體洩露了),就會給出提示,並且告訴你是哪個new(它位於哪個原始檔的哪一行)申請的記憶體沒有被釋放。
注釋:根據
ansi c
規定,__file__
表示當前原始檔的檔名,
__line__
表示**位於當前原始檔的行數。
visual c++
遵循這一規定,並且有擴充,詳見
msdn。
(四) new的三種形式
在c語言中我們分配堆記憶體一般使用malloc和free這對函式,但在 c 提供了一組操作符用於分配記憶體 new和delete,這是一組和sizeof一樣語言內建的操作符。當new與malloc分配的都是系統已有型別,即 int,char 這些系統已有型別時,兩者並無差別,都是申請記憶體,並且申請...
形式引數和實際引數的區別
形參 全稱為 形式引數 是在定義函式名和函式體的時候使用的引數,目的是用來接收呼叫該函式時傳遞的引數。實參 可以是常量 變數 表示式 函式等,無論實參是何種型別的量,在進行函式呼叫時,它們都必須具有確定的值,以便把這些值傳送給形參。因此應預先用賦值,輸入等辦法使實參獲得確定值。實參和形參的區別 空白...
new有六種過載形式
當寫出 p new p 這樣的 的時候,實際上有兩步操作,首先分配記憶體,然後在分配好的記憶體之上初始化類成員.第二步是有建構函式完成的,第一步就是new函式的工作.全域性的new有六種過載形式,void operator new std size t count throw std bad all...