內存模型描述的是程序中各變量(實例域、靜態域和數組元素)之間的關系,以及在實際計算機系統中將變量存儲到內存和從內存取出變量這樣的低層細節.不同平台間的處理器架構將直接影響內存模型的結構.
首先介紹一下C++中有繼承關系的類對象內存的布局:
在C++中,如果類中有虛函數,那麼它就會有一個虛函數表的指針__vfptr,在類對象最開始的內存數據中。之後是類中的成員變量的內存數據。
對於子類,最開始的內存數據記錄著父類對象的拷貝(包括父類虛函數表指針和成員變量)。之後是子類自己的成員變量數據。
對於子類的子類,也是同樣的原理。但是無論繼承了多少個子類,對象中始終只有一個虛函數表指針。
為了探討C++類對象的內存布局,先來寫幾個類和函數
首先寫一個基類:
class Base
{
public:
virtual void f() { cout << "Base::f" << endl; }
virtual void g() { cout << "Base::g" << endl; }
virtual void h() { cout << "Base::h" << endl; }
int base;
protected:
private:
};
然後,我們多種不同的繼承情況來研究子類的內存對象結構。
1. 無虛函數集繼承
//子類1,無虛函數重載
class Child1 : public Base
{
public:
virtual void f1() { cout << "Child1::f1" << endl; }
virtual void g1() { cout << "Child1::g1" << endl; }
virtual void h1() { cout << "Child1::h1" << endl; }
int child1;
protected:
private:
};
這個子類Child1沒有繼承任何一個基類的虛函數,因此它的虛函數表如下圖:
我們可以看出,子類的虛函數表中,先存放基類的虛函數,在存放子類自己的虛函數。
2. 有一個虛函數繼承
//子類2,有1個虛函數重載
class Child2 : public Base
{
public:
virtual void f() { cout << "Child2::f" << endl; }
virtual void g2() { cout << "Child2::g2" << endl; }
virtual void h2() { cout << "Child2::h2" << endl; }
int child2;
protected:
private:
};
當子類重載了父類的虛函數,則編譯器會將子類虛函數表中對應的父類的虛函數替換成子類的函數。
3. 全部虛函數都繼承
//子類3,全部虛函數重載
class Child3 : public Base
{
public:
virtual void f() { cout << "Child3::f" << endl; }
virtual void g() { cout << "Child3::g" << endl; }
virtual void h() { cout << "Child3::h" << endl; }
protected:
int x;
private:
};
C++ Primer Plus 第6版 中文版 清晰有書簽PDF+源代碼 http://www.linuxidc.com/Linux/2014-05/101227.htm
讀C++ Primer 之構造函數陷阱 http://www.linuxidc.com/Linux/2011-08/40176.htm
讀C++ Primer 之智能指針 http://www.linuxidc.com/Linux/2011-08/40177.htm
讀C++ Primer 之句柄類 http://www.linuxidc.com/Linux/2011-08/40175.htm
將C語言梳理一下,分布在以下10個章節中:
更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2014-12/111047p2.htm