多态和多态对象模型

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个字节大小,就是一个指针的大小。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值