C++單一、多重繼承下的記憶體模型

來源:互聯網
上載者:User

標籤:image   splay   繼承   ...   his   最簡   inf   UNC   vat   

一:C++單一繼承下的記憶體模型:

a)、最簡單的一種單一繼承記憶體模型:基類及衍生類別中無virtual function member:

#include <iostream>class Base{public:    Base(char _x = ‘\0‘) :m_x(_x) {}    ~Base() {}private:    char m_x;};class Derived :public Base{public:    Derived(char _x = ‘\0‘,int _y = 0,int _s = 0) :Base(_x), m_y(_y),m_z(_s) {}    ~Derived() {}private:    int m_y;    int m_z;};int main(){    Derived d(‘A‘,20,30);        return 0;}

    在MSVC2015 Debug ×86下,&d = 0x00eff88c;&d.m_x = 0x00eff88c;&d.m_y = 0x00eff890;&d.m_z = 0x00eff894;至於d.m_x為什麼會佔用4個位元組空間大小,這個跟記憶體對齊有關,由此可見,在單一繼承下且類中non-virtual function member時,在衍生類別中記憶體模型:地址由低到高,分別為:衍生類別對象中基類子物件資料成員地址(順序由基類中資料成員申明先後有關)、衍生類別特有對象資料成員地址(同上);

b)、單一繼承下有virtual function member情況下:

#include <iostream>class Base{public:    Base(char _x = ‘\0‘) :m_x(_x) {}    virtual void Show() { std::cout<<"this is BaseClass"<<std::endl; }    ~Base() {}private:    char m_x;};class Derived :public Base{public:    Derived(char _x = ‘\0‘,int _y = 0,int _s = 0) :Base(_x), m_y(_y),m_z(_s) {  }    virtual void Show() { std::cout << "this is Derived" << std::endl; }    ~Derived() {}private:    int m_y;    int m_z;};int main(){    Derived d(‘A‘,20,30);        return 0;}

同樣是在上述環境下,取&d = 0x0133f730;&d.m_x = 0x00133f734;&d.m_y = 0x00133f738;&d.m_z = 0x00133f73c;發現&d!=&d.m_x,這是由於在這四個位元組的記憶體空間當中,存放了指向virtual function table(此為一列表格(可將其理解為數組),此表格中存放的是類中virtual function地址,vptr指向第一個在類中申明的virtual地址)的地址vptr;由此可以看到,在單繼承模型中,衍生類別對象的記憶體模型:地址由低到高,分別為:vptr所指向的地址,衍生類別對象中基類子物件資料成員地址(順序由基類中資料成員申明先後有關)、衍生類別特有對象資料成員地址(同上);

二:C++多重繼承下的記憶體模型:

這也是C++與其他Object-Oriented程式設計語言如:java,C#的一個很大的不同,在java和C#當中取消了多重繼承,取而代之的是通過繼承介面的方式實現一種多繼承;

#include <iostream>class Base1{public:    Base1(char _x = ‘\0‘) :m_x(_x) {}    virtual void Show() { std::cout<<"this is Base1Class"<<std::endl; }    ~Base1() {}private:    char m_x;};class Base2{public:    Base2(int _a = 0):m_a(_a) {}    virtual void display() { std::cout << "this is Base2Class" << std::endl; }private:    int m_a;};class Derived :public Base1,Base2{public:    Derived(char _x = ‘\0‘,int _a = 0,int _y = 0,int _s = 0) :Base1(_x), Base2(_a),m_y(_y),m_z(_s) {  }    virtual void Show() { std::cout << "this is Derived inherited by Base1" << std::endl; }    virtual void display() { std::cout << "this is Dervied inherited by Base2" << std::endl; }    ~Derived() {}private:    int m_y;    int m_z;};int main(){    Derived d(‘A‘,10,20,30);        return 0;}

記憶體位址分布如下:

此時可以看到,在衍生類別物件模型中,地址由低到高,分別為:在繼承申明時,衍生類別中第一個基類子物件的vptr,衍生類別中第一個基類子物件的地址;衍生類別中第二個基類子物件的vptr,衍生類別中第二個基類子物件的地址....由此進行類推;

總結:從上述分析可知,在衍生類別對象的記憶體模型當中,地址從低到高,分別為:基類當中vptr所指向的地址-->衍生類別中基類子物件地址-->衍生類別vptr所指向的地址-->衍生類別中特有對象的地址:

值得一提的是在發生類似於菱形繼承時,通過virtual 繼承方式,對象的記憶體模型會更加複雜;

C++單一、多重繼承下的記憶體模型

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.