本篇筆記主要分為兩個主要部分,第一部分關於物件模型,第二部分是關於new和delete的更加深入的學習。
只要用到了虛函式,物件中就會多乙個指向虛函式表的虛指標。在32位環境下,將佔4bytes的空間。
在vtbl中,每一項都是指向自己類應當呼叫的虛函式的函式指標。
這裡提一下,如果父類定義成虛函式,子類中和父類虛函式相同名稱,參數列相同的函式會自動變成虛函式。不管加沒有virtual關鍵字。通常我們還是要加上關鍵字來確保**可讀性。
在c中,對於不同的函式名採用靜態繫結的方法,每個函式直接對應了乙個位址,儲存在相應的位置中。在c++中,非虛的成員函式也用靜態繫結的方式被儲存。如上圖中的a::func1()等成員函式。
不過對於虛函式,c++中採用了動態繫結的方法。在上圖中,每個虛函式都儲存在虛函式表中。當呼叫虛函式時,編譯器會隨著上圖中的路徑找到正確的函式呼叫。
由於動態繫結,不管什麼地方呼叫虛函式,總能得到正確的結果這個機制限制了虛函式應該被虛函式覆蓋。
虛函式可以由以下的兩種方式得到。
乙個非常常用的基於虛函式的方式是建立乙個指向抽象類的指標鍊錶,這是多型的體現。
關於類的物件模型的記憶體分配,涉及到物件的位對齊的規則,在部落格中的另一篇文章中有簡單介紹。
預設的乙個定位new函式是:
void*operatornew(size_t size,void*start)
在使用時可以採用例如如下的方法:int *p = new(0x12345678) int;
事實上,我們還可以使用別的引數列進行new操作,我們也可以對operator new和operator delete進行過載。例如下面的兩個常用的引數列:
void*operatornew(size_t size,longextra)
//extra
引數用於多申請一段儲存空間,專門用來儲存一些特別的資訊,例如引用計數的資訊。
void*operatornew(size_t size,longextra,charinit)
new和delete操作固有的定義是:
inlinevoid*operatornew(size_t size)
inlinevoid*operatornew(size_t size)//
這裡在呼叫時
size
會自動進行計算。
inlinevoidoperatordelete(void*ptr)
inlinevoidoperatordelete(void*ptr)
注意,如果需要進行過載,new第乙個引數始終應該是size_t格式的,delete的第乙個引數始終是void*型別。此外,通常情況下有引數的delete不會被呼叫,而是繼續採用無參的方法,直接釋放記憶體。
此外,new和delete也可以作為類的成員函式過載,這樣過載出來的操作將僅用於這個類。需要注意的是,new和delete操作應該是靜態的,其原因在於:
1.建立物件時,先分配記憶體,此時沒有物件,只能是靜態的。
2.刪除物件,先執行析構,析構後已經沒有物件了,所以這裡也只能是靜態的。
只有當建構函式失敗時,才會去尋找匹配的operator delete函式去釋放空間;如果沒有定義相應的delete函式,就代表放棄處理建立失敗的這一異常。
注: 當一對operator new 和operator delete除了第乙個引數之外,剩下的引數都一致時,稱這兩個操作"匹配"。
從new操作顯式丟擲異常,並不會觸發特殊的delete。從new操作中丟擲異常,代表記憶體分配沒有進行,因此也就不需要釋放記憶體;只有再分配記憶體之後,構造時產生異常才會觸發特殊的delete。
下面是關於new、delete操作的測試**:
1標頭檔案#ifndef header_h_included
2#define header_h_included
3 #include 4 #include 5
using
namespace
std;
6class
fruit
12virtual
void
process()
13 fruit(int n = 0,double w = 0,char k = 0):no(n),weight(w),key(k)
14virtual ~fruit()
15};
1617
fruit
22virtual
void
process()
):fruit(n,w,k),size(s),type(t)
3031 cout<
"<
33static
void * operator
new(size_t size);
34static
void * operator
new(size_t size,long
extra);
35static
void
operator
delete(void *ptr);
36static
void
operator
delete(void* ptr,long
extra);
37};
38void* operator
new(size_t size)
3943
void
operator
delete(void*ptr)
4448
4950
#endif
//header_h_included
1 #include "header.h"2
3using
namespace
std;45
new(size_t size)610
11new(size_t size,long
extra)
1216
1718
delete(void*ptr)
1923
delete(void* ptr,long
extra)
2428
29int
main()
3056
catch
(...)
5760
return0;
61 }
高階程式設計技術作業 5
題目描述 使用乙個for迴圈列印數字1 20 包含 展示 for number in range 1,21 print number input null output 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 題目描述 通過給函式rang...
高階程式設計技術作業 7
題目描述 使用乙個字典來儲存一些人喜歡的數字。請想5個人的名字,並將這些名字用作字典中 的鍵 想出每個人喜歡的乙個數字,並將這些數字作為值儲存在字典中。列印每個人的名字和喜歡 的數字。展示 dic for name,number in dic.items print name str number ...
高階程式設計技術作業 8
題目描述 編寫乙個迴圈,提示使用者輸入一系列的比薩配料,並在使用者輸入 quit 時結束迴圈。每當 使用者輸入一種配料後,都列印一條訊息,說我們會在比薩中新增這種配料。input potato tomato fish quit output please input an ingredient we...