轉載自http://blog.csdn.net/it_yuan/article/details/24651347html
#類中的元素函數
0. 成員變量 1. 成員函數 2. 靜態成員變量 3. 靜態成員函數 4. 虛函數 5. 純虛函數佈局
#影響對象大小的因素this
0. 成員變量 1. 虛函數表指針(_vftptr) 2. 虛基類表指針(_vbtptr) 3. 內存對齊.net
_vftptr、_vbtptr的初始化由對象的構造函數, 賦值運算符自動完成;對象生命週期結束後,由對象的析構函數來銷燬。
對象所關聯的類型(type_info),一般放在virtual table的第一個slot中。3d
虛繼承:在繼承定義中包含了virtual關鍵字的繼承關係;
虛基類:在虛繼承體系中的經過virtual繼承而來的基類,須要注意的是:
class CDerive : public virtual CBase {}; 其中CBase稱之爲CDerive的虛基類,而不是說CBase就是個虛基類,由於CBase還能夠爲不是虛繼承體系中的基類。指針
虛函數被派生後,仍然爲虛函數,即便在派生類中省去virtual關鍵字。code
注:【下文中_vbptr即_vbtptr】htm
#對象內存佈局分類討論對象
vc6變量查看器中(Locals,Watch1等),也能夠看到部分對象佈局的狀況(不完整,且虛繼承是錯誤的)。
vs2005及之後版本的編譯器提供了/d1reportSingleClassLayout[類名]編譯選項來查看對象完整的內存佈局:
cl classLayout.cpp /d1reportSingleClassLayoutCChildren
0. 單一類
(1). 空類
sizeof(CNull)=1(用於標識該對象)
(2). 只有成員變量的類
int nVarSize = sizeof(CVariable) = 12
內存佈局:
(3). 只有虛函數的類
int nVFuntionSize = sizeof(CVFuction) = 4(虛表指針)
內存佈局:
(4). 有成員變量、虛函數的類
int nParentSize = sizeof(CParent) = 8
內存佈局:
1. 單一繼承(含成員變量、虛函數、虛函數覆蓋)
int nChildSize = sizeof(CChildren) = 12
vc中顯示的結果(注:還有1個虛函數CChildren::g1沒有被顯示出來):
d1reportSingleClass查看:
內存佈局:
2. 多繼承 (含成員變量、虛函數、虛函數覆蓋)
int nChildSize = sizeof(CChildren) = 20
vc中顯示的結果(注:還有2個虛函數CChildren::f2,CChildren::h2沒有被顯示出來,this指針的adjustor[調整值]也沒打印出):
d1reportSingleClass查看:
內存佈局:
3. 深度爲2的繼承(含成員變量、虛函數、虛函數覆蓋)
int nGrandSize = sizeof(CGrandChildren) = 24
vc中顯示的結果(注:還有3個虛函數CGrandChildren::f2,CChildren::h2,CGrandChildren::f3沒有顯示出來,this指針的adjustor[調整值]也沒打印出):
d1reportSingleClass查看:
內存佈局:
4 重複繼承(含成員變量、虛函數、虛函數覆蓋)
int nGrandSize = sizeof(CGrandChildren) = 28
vc中顯示的結果(注:還有大量的虛函數沒有顯示出來,this指針的adjustor[調整值]也沒打印出):
thunk函數:一種形實轉換輔助函數;主要作this指針調整,函數調用重定向。
d1reportSingleClass查看:
內存佈局:
因爲m_nAge在內容中存在兩個拷貝,所以咱們不能直接經過pGrandChildrenA->m_nAge來訪問該變量,
這樣會存在二義性,編譯器沒法知道應該訪問CChildren1中的m_nAge,仍是CChildren2中的m_nAge。
爲了標識惟一的m_nAge,就須要帶上其所在範圍的類名了。以下:
1 pGrandChildrenA->CChildren1::m_nAge = 1; 2 pGrandChildrenA->CChildren2::m_nAge = 2;
5. 單一虛繼承(含成員變量、虛函數、虛函數覆蓋)
int nChildSize = sizeof(CChildren) = 20
d1reportSingleClass查看:
內存佈局:
6. 多虛繼承(含成員變量、虛函數、虛函數覆蓋)
(1) virtual CParent1, CParent2
int nChildSize = sizeof(CChildren) = 24
d1reportSingleClass查看:
內存佈局:
(2) CParent1, virtual CParent2
int nChildSize = sizeof(CChildren) = 24
d1reportSingleClass查看:
內存佈局:
(3) virtual CParent1, virtual CParent2
int nChildSize = sizeof(CChildren) = 28
d1reportSingleClass查看:
內存佈局:
7. 鑽石型的虛擬多重繼承(含成員變量、虛函數、虛函數覆蓋)
int nGrandChildSize = sizeof(CGrandChildren) = 36
d1reportSingleClass查看:
thunk函數:一種形實轉換輔助函數;主要作this指針調整,函數調用重定向。
內存佈局:
#外部參考
參考連接:http://blog.csdn.net/yangshuangtao/article/details/45192149