面向對象高級編程(下)-- 第二週學習筆記(Boolan)

下面簡單圖示說明使用gcc 4.6在x86 ubuntu上vptr和vtbl(以及VTT)佈局。
關於VTT的參考連接:
http://stackoverflow.com/questions/6258559/what-is-the-vtt-for-a-classios

根據我本身的驗證,獲得下面的結論:ubuntu

  1. x86 ubuntu上char類型爲1字節,int爲4個字節,double爲8個字節,地址對齊方式是4字節對齊
    2)若是一個類沒有父類,而且沒有虛函數,那麼其對象的內存佈局就是各個數據成員按定義順序排列,並對其大小進行4字節對齊後獲得的結果。沒有vtbl,於是也沒有vptr.
    3)若是一個類沒有父類,而且有虛函數,其對象開始地址會包含一個指向本類型vtbl中第一個虛函數的指針(vptr),接下來是其各個數據成員。vtbl中前面兩項是0以及一個指向其typeinfo的指針,後面是虛函數的地址,而vptr指向本身vtbl中的第一個虛函數地址。
    4)若是一個類是從一個父類public繼承,而且父類中沒有虛函數,其對象內存佈局是其父類的數據成員,後面跟隨的是本類的數據成員。由於父類和子類都沒有虛函數,因此沒有vtbl,於是沒有vptr。
    5)若是一個類是從一個父類public繼承,而且父類中有虛函數,可是本身沒有虛函數。那麼其對象內存佈局第一個位置是指向本類型vtbl中第一個虛函數的偏移地址的指針。其vtbl中前面兩項分別是0和指向本身typeinfo的指針,第三項開始是其虛函數的偏移地址。
    6)若是一個類從父類virtual繼承,那麼還會生成VTT表(實際上其中包含指向其vtbl偏移地址的指針)。
    7)多重繼承的狀況下,其內存佈局是從基類內存佈局依次排列,而後後面跟隨本身的虛函數指針(假設有虛函數)和其數據成員。

測試代碼以下(主要考察是否有虛函數以及public和virtual繼承的差異):segmentfault

 1 #include <iostream>
 2 
 3 class NoVirtualFunc{
 4  int a;
 5  double b;
 6  char c;
 7 };
 8 
 9 class VirtualFunc{
10  int x;
11  double y;
12  char z;
13 public:
14  virtual void vfunc1(){}
15 };
16 
17 class PublicDerivedFromNoVirtualFunc: public NoVirtualFunc{
18  int pdfnvf;
19 };
20 
21 class PublicDerivedFromVirtualFunc: public VirtualFunc{
22  int pdfvf;
23 };
24 
25 class VirtualDerivedFromNoVirtualFunc: virtual NoVirtualFunc{
26  int vdfnvf;
27 };
28 
29 class VirtualDerivedFromVirtualFunc: virtual VirtualFunc{
30  int vdfvf;
31 };
32 
33 class PublicMultiple: public NoVirtualFunc, public VirtualFunc{
34  int pm;
35 };
36 
37 class VirtualMultiple: virtual  NoVirtualFunc, virtual VirtualFunc{
38  int vm;
39 };
40 
41 class AnotherVirtualFunc{
42  char c;
43 public:
44  virtual void g(){} 
45 };
46 
47 class PublicMultipleTwoVirtual:public VirtualFunc, public AnotherVirtualFunc{
48  char pmtv;
49 };
50 
51 class VirutalMultipleTwoVirtual:virtual VirtualFunc, virtual AnotherVirtualFunc{
52  char vmtv;
53 };
54 
55 int main(void)
56 {
57  NoVirtualFunc o1;
58  VirtualFunc o2;
59  
60  PublicDerivedFromNoVirtualFunc o3;
61  PublicDerivedFromVirtualFunc o4;
62  
63  VirtualDerivedFromNoVirtualFunc o5;
64  VirtualDerivedFromVirtualFunc o6;
65  
66  PublicMultiple o7;
67  VirtualMultiple o8;
68 
69  AnotherVirtualFunc o9;
70  PublicMultipleTwoVirtual o10;
71  VirutalMultipleTwoVirtual o11;
72  
73  return 0;
74 }

const

const成員函數
const能夠修飾成員函數來避免成員函數對this指針的修改。
當成員函數的const和non-const版本都存在時,const成員只能調用const版本,
non-const成員只能調用non-const版本。函數

new&delete

咱們能夠對operator new和operator delete進行各類版本的重載,可是每一個版本都須要有本身的獨特參數序列
其中第一個參數必須是size_t.
對於operator delete的各類重載版本,它們雖然能夠被重載,可是不會被delete調用,只有當new 調用的構造函數拋出異常時,它們纔會被調用,用來清除申請失敗對象的內存。
關於operator new和 operator delete的具體討論見此次做業。operator new與 delete重載佈局

固然咱們也能夠經過使用域做用符::來強制使用全局new和全局delete,調用方法是::new和::delete測試

相關文章
相關標籤/搜索