1. 程式人生 > >多型和多型物件模型

多型和多型物件模型

1 單繼承的多型,以以下程式碼為例

class A
{
public:
    virtual void f1()
    {
        cout<<"A::f1"<<endl;
    }
    virtual void f2()
    {
        cout<<"A::f2"<<endl;
    }
    void f3()
    {
        cout<<"A::f3"<<endl;
    }
};

class B :public A
{
public:
    virtual void
f1() { cout<<"B::f1"<<endl; } virtual void f2() { cout<<"B::f2"<<endl; } void f3() { cout<<"A::f3"<<endl; } }; int main() { A* a; B b; a=&b; a->f1(); a->f2(); a->f3(); return
0; }

這裡寫圖片描述
2.繼承的多型以以下程式碼為例

#include<iostream>
using namespace std;


class A
{
public:
    virtual void f1()
    {
        cout<<"A::f1"<<endl;
    }

public:
    int _a;
};
class B
{
public:
    virtual void f2()
    {
        cout<<"B::f2"<<endl;
    }
public:
    int
_b; }; class C:public B,public A { public: virtual void f3() { cout<<"C::f3"<<endl; } public: int _c; }; typedef void(*VFUNC)(); void PrintVTable(void* vtable) { printf("vtable:0x%p\n", vtable); VFUNC* array = (VFUNC*)vtable; for (size_t i = 0; array[i] != 0; ++i) { printf("vtable[%d]:0x%p->", i,array[i]); array[i](); } cout<<"================================"<<endl; } int main() { A a; B b; C c; PrintVTable(*((int**)&c)); return 0; }

這個多繼承說明了基類有虛表時,派生類會繼承基類的虛數表,並且是先繼承誰,就會把自己的虛擬函式儲存在誰的虛表中,我們通過呼叫監視視窗和列印虛表來看清這一問題。
這裡寫圖片描述
所以說C有兩個虛表。
3.菱形繼承

class A
{
public:
    virtual void f1()
    {
        cout<<"A::f1"<<endl;
    }

public:
    int _a;
};
class B:public A
{
public:
    virtual void f1()
    {
        cout<<"B::f1"<<endl;
    }
    virtual void f2()
    {
        cout<<"B::f2"<<endl;
    }
public:
    int _b;
};
class C:public A
{
public:
    virtual void f3()
    {
        cout<<"C::f3"<<endl;
    }
public:
    int _c;
};
class D:public B,public C
{
public:
    virtual void f1()
    {
        cout<<"D::f1"<<endl;
    }
    virtual void f4()
    {
        cout<<"D::f4"<<endl;
    }
public:
    int _d;

};


typedef void (*V_FUNC)();  
void PrintVTable(int vtable)  
{  
    int* VfArray = (int*)vtable;  
    printf("vtable:0x%p\n",VfArray);  
    for(int i = 0;VfArray[i] != 0;++i)  
    {  
        printf("vfun[%d]:0x%p->",i,VfArray[i]);  
        V_FUNC f = (V_FUNC)VfArray[i];  
        f();  
    }  
    cout<<"*********************************"<<endl;  
}  
int main()
{
    A a;
    B b;
    C c;
    D d;
    d.B::_a=1;
    d.C::_a=2;
    d._b=3;
    d._d=4;

    PrintVTable(*((int*)&d));  
    PrintVTable(*(int*)((char*)&d+12));  

    return 0;
}

這裡寫圖片描述
菱形繼承也符合單繼承和多繼承的規律
總結:
當基類有虛擬函式即有虛表時,派生類就會繼承其虛表。一個只有虛表的類就是4個位元組大小,就是一個指標的大小。