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

首頁 > 編程 > C++ > 正文

C++對象模型

2019-11-08 18:21:08
字體:
供稿:網(wǎng)友

一.單繼承的對象模型

class Car{public:    virtual void func1()    {        cout << "Car::func1()" << endl;    }    virtual void func2()    {        cout << "Car::func2()" << endl;    }PRotected:    int _c;//種類};class Bike :public Car{public:    virtual void func1()    {        cout << "Bike::func1()" << endl;    }    virtual void func2()    {        cout << "Bike::func2()" << endl;    }    virtual void func3()    {        cout << "Bike::func3()" << endl;    }protected:    int _b;//自行車數(shù)量};int main(){    Car c;    Bike b;    system("pause");    return 0;}通過這種表我們對單繼承有個初步的了解,可以看道派生類Bike::func1重寫(覆蓋)了父類Car::func1,覆蓋了虛表函數(shù)的位置。但是我們細(xì)心發(fā)現(xiàn),派生類Bike::func3消失了。我們可以打印函數(shù)的地址打開內(nèi)存看個究竟:
class Car{public:    virtual void func1()    {        cout << "Car::func1()" << endl;    }    virtual void func2()    {        cout << "Car::func2()" << endl;    }protected:    int _c;//種類};class Bike :public Car{public:    virtual void func1()    {        cout << "Bike::func1()" << endl;    }    virtual void func2()    {        cout << "Bike::func2()" << endl;    }    virtual void func3()    {        cout << "Bike::func3()" << endl;    }protected:    int _b;//自行車數(shù)量};typedef void(*FUNC) ();void PrintfVtable(void *_vfptr){    int *Vtable = (int *)_vfptr;    printf("虛表的地址Vtable:0x%x/n",Vtable);    for (size_t i = 0; Vtable[i] != 0; ++i)    {        printf("第%d個虛函數(shù)的地址:0x%x/n", i, Vtable[i]);        FUNC f = (FUNC)Vtable[i];        f();    }}int main(){    Car c;    Bike b;    int *Vtable1 = (int*)(*((int*)&c));    int *Vtable2 = (int*)(*((int*)&b));    PrintfVtable(Vtable1);    PrintfVtable(Vtable2);    system("pause");    return 0;}我們畫一下它的對象模型:

三.菱形對象

class AA{public:    virtual void fun1()    {        cout << "AA::fun1()" << endl;    }    virtual void funA()    {        cout << "AA::funA()" << endl;    }public:    int _aa;};class BB :public AA{public:    virtual void fun1()    {        cout << "BB::funB()" << endl;    }    virtual void funB()    {        cout << "BB::funB()" << endl;    }public:    int _bb;};class CC :public AA{public:    virtual void fun1()    {        cout << "CC::fun1()" << endl;    }    virtual void funC()    {        cout << "CC::funC()" << endl;    }public:    int _cc;};class DD :public BB,public CC{public:    virtual void fun1()    {        cout << "DD::fun1()" << endl;    }    virtual void funD()    {        cout << "DD::funD()" << endl;    }public:    int _dd;};typedef void(*FUNC)();void PrintfVtable(void *_vfptr){         int*Vtable = (int *)_vfptr;        printf("虛表的地址Vtable:0x%x/n",Vtable);        for (size_t i = 0; Vtable[i] != 0; ++i)        {            printf("第%d個虛函數(shù)的地址:0x%x/n", i, Vtable[i]);            FUNC f = (FUNC)Vtable[i];            f();        }   }int main(){    DD d;    d.BB::_aa = 0;    d.CC::_aa = 1;    d._bb  = 2;    d._cc = 3;    d._dd = 4;    int *Vtable1 = (int*)(*((int*)&d));    PrintfVtable(Vtable1);    system("pause");    return 0;}通過上面我們很清楚的看到有兩個虛表分別存放虛函數(shù)的地址,第一個存放派生類DD::fun1()的地址和AA::funA();第二個虛函數(shù)存放AA::funA()的地址。這里面就出現(xiàn)菱形繼承的問題二義性和數(shù)據(jù)的冗余的問題。通過觀察內(nèi)存看到。

三.菱形虛擬繼承

在public前面加上關(guān)鍵字virtual:class AA{public:    virtual void fun1()    {        cout << "AA::fun1()" << endl;    }    virtual void funA()    {        cout << "AA::funA()" << endl;    }public:    int _aa;};class BB :virtual public AA{public:    virtual void fun1()    {        cout << "BB::funB()" << endl;    }    virtual void funB()    {        cout << "BB::funB()" << endl;    }public:    int _bb;};class CC :virtual public AA{public:    virtual void fun1()    {        cout << "CC::fun1()" << endl;    }    virtual void funC()    {        cout << "CC::funC()" << endl;    }public:    int _cc;};class DD :public BB,public CC{public:    virtual void fun1()    {        cout << "DD::fun1()" << endl;    }    virtual void funD()    {        cout << "DD::funD()" << endl;    }public:    int _dd;};typedef void(*FUNC)();void PrintfVtable(void* _vptr){    int *Vtable = (int*)_vptr;    printf("虛表的地址)0x%x/n", Vtable);        for (size_t i = 0; Vtable[i] != 0; ++i)        {            printf("第%d個虛函數(shù)的地址:0x%x/n", i, Vtable[i]);            FUNC f = (FUNC)Vtable[i];            f();        }   }int main(){    DD d;    d.BB::_aa = 0;    d.CC::_aa = 1;    d._bb  = 2;    d._cc = 3;    d._dd = 4;    int *Vtable = (int*)(*((int*)&d));    PrintfVtable(Vtable);    system("pause");    return 0;}前面我們也知道菱形繼承就是多繼承的一種,看到上面也發(fā)現(xiàn)多繼承與單繼承的區(qū)別,至于多繼承的模型我們下次繼續(xù)。。。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表

圖片精選

主站蜘蛛池模板: 昌乐县| 静安区| 隆昌县| 渭源县| 彰化县| 泰顺县| 兴和县| 广东省| 乌拉特中旗| 稷山县| 新兴县| 囊谦县| 密云县| 万荣县| 渭源县| 潼关县| 和顺县| 庄浪县| 增城市| 清河县| 会东县| 华安县| 格尔木市| 寿光市| 蕉岭县| 阜新市| 日照市| 陆良县| 高邑县| 沈阳市| 台南市| 卢龙县| 德保县| 浦东新区| 永春县| 盐边县| 滦平县| 延寿县| 贵阳市| 邵阳市| 新疆|