過載new和delete運算子
前面已經介紹了如何用new和delete運算子函式來動態第管理記憶體,在那些例子中使用的都是全域性的new和delete運算子。我們可以過載全域性的new和delete運算子,但這不是好的想法,除非在進行低階的系統上或者嵌入式的程式設計。
但是,在某個類的內部過載new和delete運算子時可以的。這允許乙個類有它自己的new和delete運算子。當乙個類需要和記憶體打交道時,採用這種方法來處理其中的細節,可以獲得很搞的效率,同時避免了使用全域性new和delete運算子帶來的額外開銷。因為全域性堆操作時呼叫作業系統函式來分配和釋放記憶體,這樣效率很低。
如果確定某個類在任何時候,其實例都不會超過乙個確定的值,那麼就可以一次性為類的所有例項分配足夠的記憶體,然後用該類的new和delete運算子來管理這些記憶體。下面的程式說明了如何對new和delete進行過載。
#include iostream.h
#include string.h
#include stddef.h
#include new.h
const int maxnames = 5;
class names
void* operator new(size_t) throw(bad_alloc);
void operator delete(void*) throw();
void display() const ;
char names::pool[maxnames * sizeof(names)];
bool names::inuse[maxnames];
void* names::operator new(size_t) throw(bad_alloc)
}throw bad_alloc();
} void names::operator delete(void* p) throw()
int main()
for(i=0; i
return 0;
} 上面的程式提示輸入5個姓名,然後顯示它們。程式中定義了名為names的類,它的建構函式初始化物件的name值。這個類定義了自己的new和delete運算子。這是因為程式能保證不會一次使用超過maxnames個姓名,所以可以通過過載預設的new和delete運算子來提高執行速度。
names類中的記憶體池是乙個字元陣列,可以同時容納程式需要的所有姓名。與之相關的布林型陣列inuse為每個姓名記錄了乙個true和false值,指出記憶體中的對應的項是否正在使用。
過載的new運算子在記憶體池中尋找乙個沒有被使用的項,然後返回它的位址。過載的delete運算子則標記那些沒有被使用的項。
在類定義中過載的new和delete運算子函式始終是靜態的,並且沒有和物件相關的this指標。這是因為編譯器會在呼叫建構函式之前呼叫new函式,在呼叫析構函式後呼叫delete函式。
new函式是在類的建構函式之前被呼叫的。因為這時記憶體中還不存在類的物件而且建構函式也沒有提供任何初始化值,所以它不可以訪問類的任何成員。同理,delete運算子是在析構函式之後被呼叫的,所以它也不可以訪問類的成員。
2023年計算機二級考試C語言輔導常用庫函式1
absread 讀磁碟絕對扇區函式 原形 int absread int drive,int num,int sectnum,void buf 功能 從drive指定的驅動器磁碟上,sectnum指定的邏輯扇區號開始讀取 通過dos中斷0x25讀取 num個 最多64k個 扇區的內容,儲存於buf所...
2023年計算機二級考試C語言輔導常用庫函式2
標頭檔案 bcd.h bdos 原形 int bdos int fnum,unsigned dx,unsigned al 其中fnum是系統呼叫號 dx是傳給暫存器dx的值 al是傳給暫存器al的值 功能 dos系統呼叫 int21h 返回值 ax中的值 biosdisk 呼叫bios磁碟驅動程式函...
2023年計算機二級考試c 輔導筆記類和堆2
堆和類陣列 前面提到,類物件陣列的每個元素都要呼叫建構函式和析構函式。下面的例子給出了乙個錯誤的釋放類陣列所占用的記憶體的例子。include iostream.h class date int main 指標dt指向乙個有五個元素的陣列。按照陣列的定義,編譯器會讓new運算子呼叫date類的建構函...