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

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

菱形虛擬繼承和多態

2019-11-08 19:46:28
字體:
來源:轉載
供稿:網友

一.菱形繼承(多繼承)

class AA{public:    int _aa;};class BB : public AA{public:    int _bb;};class CC : public AA{public:    int _cc;};class DD :public BB, public CC{public:    int _dd;};int main(){    DD d;    d.BB::_aa = 0;    d._bb = 1;    d.CC::_aa = 2;    d._cc = 3;    d._dd = 4;  cout << sizeof(DD) << endl;    system("pause");    return 0;}

通過內存我們可以看到菱形繼承的缺點是:1.二義性,2.數據的冗余

為了更加直觀我們畫圖看一下:

2.如何解決菱形繼承的缺點

二.虛繼承:

class AA{public:    int _aa;};class BB : public AA{public:    int _bb;};class CC : public AA{public:    int _cc;};class DD :public BB, public CC{public:    int _dd;};int main(){    DD d;    d.BB::_aa = 0;    d._bb = 1;    d.CC::_aa = 2;    d._cc = 3;    d._dd = 4;  cout << sizeof(DD) << endl;    system("pause");    return 0;}

通過內存我們發現此時_aa的對象只有一個就是CC,這樣二義性就解決了,同時我們發現派生類BB中的_aa消失,這樣就解決了數據的冗余的問題。但是我們發現有多處兩組地址。通過查看oxo13bdd94和oxo13be308的地址我們可以看到一個偏移了第一個偏移20個字節剛好到基類AA,第二個偏移12個字節剛好到基類AA.

菱形的虛繼承我們可以通過圖形表示如下:

結果是24,按虛繼承的優點內存的大小應該是18,為什么會多出8個字節,根據前面我們知道,多出來的字節用于存放偏移地址。通過虛繼承我們發現雖然解決了菱形繼承的問題,但是一定程度上是空間換時間為代價的。

三.虛函數&多態

class Shopping{public:   void PRice()    {        cout << "不優惠" << endl;    }};class OnLine :public Shopping{public:   void Price()    {        cout << "優惠" << endl;    }};void fun(Shopping &s){    s.Price();}int main(){    Shopping s;    OnLine  o;    fun(s);    fun(o);    system("pause");    return 0;}

結果顯示“不優惠”調了兩次,按照兼容規則可知道父類的指針和引用可以指向子類的對象。

1.虛函數:

類的成員函數前面加關鍵字virtual,那么這個成員函數就是虛函數。如:
#include<iostream>using namespace std;class Shopping{public:    virtual void Price()    {        cout << "不優惠" << endl;    }};class OnLine :public Shopping{    virtual void Price()    {        cout << "優惠" << endl;    }};void fun(Shopping &s){    s.Price();}int main(){    Shopping s;    OnLine  o;    fun(s);    fun(o);    system("pause");    return 0;}

結果顯示“優惠”和“不優惠”虛函數的重寫:當子類的虛函數與父類相同時,子類的這個函數重寫了父類的虛函數。可以理解為把這個父類的虛函數覆蓋了。

2.多態:

當基類的指針或引用調用的重寫的虛函數時,當指向父類調用的就是父類的虛函數,當指向子類調用的就是子類的虛函數。

3.協變:

協變也是一種重寫,只不過父類和字類中的返回值不同。
class Person{public:    Person()        :_id(1)    {}    virtual void Display()    {        cout << "_id(1)"<< endl;    }protected:    int  _id; // 身份證號};class Student : public Person{public:    Student()        :_id(2)    {}    virtual void Display()    {        cout << "_id(2)" << endl;    }protected:    int _id; // 身份證號};int main(){    Student s;    s.Display();    cout << sizeof(s) << endl;    system("pause");    return 0;}

通過結果我們可以看到,協變其實就是重寫,基類函數的虛函數被子類的虛函數覆蓋了。id(1)只是被隱藏但仍然存在。查看監視窗口我們會發現基類下面除了內存外還存在一個虛函數表指針_vfptr指向虛函數表,用于存放函數地址

查看內存窗口我們可以看到原來多出的4個字節用于存放虛表指針的地址。

通過上面我們知道多態的原理實際就是虛函數的重寫,(協變例外)


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 济阳县| 唐河县| 广安市| 新乡市| 内江市| 河南省| 拉孜县| 新源县| 高陵县| 仙桃市| 汝南县| 凯里市| 简阳市| 文安县| 太湖县| 喜德县| 刚察县| 九江市| 桐庐县| 邹城市| 金乡县| 双辽市| 吴忠市| 平阳县| 韩城市| 阿克陶县| 广汉市| 大连市| 休宁县| 繁峙县| 冕宁县| 临桂县| 珠海市| 文登市| 安阳县| 海原县| 绍兴县| 丽江市| 昂仁县| 澄江县| 图木舒克市|