国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

面試常見題之虛函數及底層的實現

2019-11-08 01:27:41
字體:
來源:轉載
供稿:網友

一.菱形對象模型(成員函數+虛函數的覆蓋)

class AA{public:    virtual void fun1()    {        cout << "AA::fun1()" << endl;    }public:    int _aa;};class BB :public AA{public:    virtual    void fun1()    {        cout << "BB::fun1()" << endl;    }public:    int _bb;};class CC :public AA{public:    virtual    void fun1()    {        cout << "CC::fun1()" << endl;    }public:    int _cc;};class DD :public BB, public CC{public:    virtual    void fun1()    {        cout << "DD::fun1()" << endl;    }public:    int _dd;};int main(){    DD d;    d.BB::_aa = 1;    d.CC::_aa = 2;    d._bb = 3;    d._cc = 4;    d._dd = 5;cout << sizeof(d) << endl;    system("pause");    return 0;}前面也提到過,菱形繼承會存在數據的冗余和二義性。那如果加上虛函數結果會怎樣呢?我們知道有虛表指針存放虛函數的地址;我們再從內存的角度觀察一下:

觀察結果:

我們畫出菱形的對象模型如下:

現在我們再來分析內存為什么是28個字節,BB對象中有一個虛表指針_vfptr存放重寫派生類DD::fun1()虛函數的地址,BB的對象中還有從派生類AA繼承的整形_aa和自己類中的_bb;CC的對象中有一個虛表指針_vfptr 重寫了派生類DD::fun1()的虛函數的地址,以及自己從基類集成的_aa;DD的對象中只有自己類中的_dd。這樣我們就很容易搞明白28個字節的原因了。

二.菱形虛繼承(虛函數的重寫)

#include<iostream>using namespace std;class AA{public:    virtual void fun1()    {        cout << "AA::fun1()" << endl;    }public:    int _aa;};class BB :virtual public AA{public:    virtual    void fun1()    {        cout << "BB::fun1()" << endl;    }    virtual    void fun2()    {        cout << "BB::fun2()" << endl;    }public:    int _bb;};class CC :virtual public AA{public:    virtual    void fun1()    {        cout << "CC::fun1()" << endl;    }    virtual    void fun2()    {        cout << "CC::fun2()" << endl;    }public:    int _cc;};class DD :public BB, public CC{public:    virtual    void fun1()    {        cout << "DD::fun1()" << endl;    }    virtual    void fun2()    {        cout << "DD::fun2()"<< endl;    }public:    int _dd;};int main(){    DD d;    d.BB::_aa = 1;    d.CC::_aa = 2;    d._bb = 3;    d._cc = 4;    d._dd = 5;    cout << sizeof(d) << endl;    system("pause");    return 0;}

但是結果是36,我們再從監視窗口來看,我們看到有兩個虛表指針,有兩層意思,第一層派生類的虛函數BB::fun2()重寫了基類的虛函數AA::fun2().,第二層派生類DD::fun2()有重寫了虛函數BB::fun2()。我們再畫出菱形對象的模型如下:來分析內存的大小為什么是36,對象BB我們可以理解有三部分組成,一個虛表指針存放虛函數DD::fun2()的地址,一個虛基址指針用來存放BB對象的偏移量,整型_bb對象CC也有三部分組成,一個虛表指針存放虛函數DD::fun2()的地址,一個 虛基表指針存放CC對象的偏移量,以及整形_cc。對象DD只有整形_dd,對象AA有兩部分虛表指針和整形_aa.

三.總結

虛函數的作用:虛函數的重寫是實現多態的條件,通過虛表指針調用相應的函數實現。虛繼承的作用:1.解決菱形繼承的二義性和數據冗余的問題,2.底層實現原理與編譯器相關,一般通過虛基類 指針實現,即各對象中只保存一份父類的對象,多繼承時通過虛基類指針引用該公共對象,從而避 免菱形繼承中的二義性問題。對象模型前面也有介紹http://blog.csdn.net/f2016913/article/details/55292948以及菱形繼承http://blog.csdn.net/f2016913/article/details/55225939


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 冕宁县| 大田县| 北海市| 凉城县| 固镇县| 呼玛县| 新巴尔虎右旗| 湖州市| 屏东县| 涟水县| 鸡西市| 牡丹江市| 临武县| 延边| 杭锦后旗| 溧阳市| 新营市| 离岛区| 芮城县| 于田县| 吴旗县| 合阳县| 阳山县| 凤台县| 神池县| 永新县| 阜城县| 深圳市| 内乡县| 略阳县| 巨鹿县| 松阳县| 安阳市| 开江县| 澜沧| 赤城县| 巴南区| 丹阳市| 隆德县| 都江堰市| 奉化市|