多态的对象模型

1:所谓多态就是多种形态,在两个类中,函数名相同的函数,通过不同对象的调用,产生不同的结果。多态和类型无关,只和对象有关。
构成多态的条件:(1)虚函数的重写:子类中和父类相同点的虚函数
(2)父类的指针/引用调用虚函数
当指向父类的指针或引用调用重写的虚函数时,当指向父类调用的就是父类的虚函数,当指向子类调用的就是子类的虚函数。
2:多态的对象模型
单继承

class Base
{
public:
    virtual void fun1()
    {
        cout<<"Base::fun1()"<<endl;
    }
    virtual void fun2()
    {
        cout<<"Base::fun2()"<<endl;
    }
private:
    int a;
};

class Derive:public Base
{
public:
    virtual void fun1()
    {
        cout<<"Derive::fun1()"<<endl;
    }
    virtual void fun3()
    {
        cout<<"Derive::fun3()"<<endl;
    }
    virtual void fun4()
    {
        cout<<"Derive::fun4()"<<endl;
    }
private:
    int b;
};
int main()
{
    Base b;
    Derive d;

    int* vtable1 = (int*)(*(int*)&b);
    int* vtable2 = (int*)(*(int*)&d);

    PrintVTable(vtable1);
    PrintVTable(vtable2);
    return 0;
}

这里写图片描述

typedef void(* FUNC)();//函数指针(指向函数的指针)

void PrintVTable(int* VTable)//打印虚函数表
{
    cout<<"VTable: "<<VTable<<endl;
    for(int i=0; VTable[i] != 0; ++i)
    {
        printf("VTable[i]: 0x%x,->",i,VTable[i]);
        FUNC f = (FUNC)VTable[i];
        f();
    }
    cout<<endl;
}

这里写图片描述

这里写图片描述

多继承

class AA
{
public:
    virtual void fun1()
    {
        cout<<"AA::fun1()"<<endl;
    }
    virtual void fun2()
    {
        cout<<"AA::fun2()"<<endl;
    }
private:
    int _a;
};

class BB
{
public:
    virtual void fun1()
    {
        cout<<"BB::fun1()"<<endl;
    }
    virtual void fun2()
    {
        cout<<"BB::fun2()"<<endl;
    }
private:
    int _b;
};

class CC : public AA,public BB
{
public:
    virtual void fun1()
    {
        cout<<"CC::fun1()"<<endl;
    }
    virtual void fun3()
    {
        cout<<"CC::fun3()"<<endl;
    }
private:
    int _c;
};

typedef void(*FUNC)();

void PrintVTable(int* VTable)
{
    cout<<"VTable: "<<VTable<<endl;
    for(int i=0; VTable[i] != 0; ++i)
    {
        printf("VTable[i]:0x%x,->",i,VTable[i]);
        FUNC f = (FUNC)VTable[i];
        f();
    }
    cout<<endl;
}

int main()
{
    CC c;
    int* vtable = (int*)(*(int*)&c);
    PrintVTable(vtable);

    vtable = (int*)(*((int*)&c+sizeof(AA)/4));
        //sizeof(AA)=8除4为int*的个数
    PrintVTable(vtable);
    return 0;
}

这里写图片描述

**菱形继承

//菱形继承的多态对象模型
class A
{
public:
    virtual void fun1()
    {
        cout<<"A::fun1()"<<endl;
    }
public:
    int _a;
};

class B : public A
{
public:
    virtual void fun1()
    {
        cout<<"B::fun1()"<<endl;
    }
    virtual void fun2()
    {
        cout<<"B::fun2()"<<endl;
    }

public:
    int _b;
};

class C : public A
{
public:
    virtual void fun1()
    {
        cout<<"C::fun1()"<<endl;
    }
    virtual void fun3()
    {
        cout<<"C::fun3()"<<endl;
    }

public:
    int _c;
};

class D : public B,public C
{
public:
    virtual void fun1()//重写B,C中的虚函数
    {
        cout<<"D::fun1()"<<endl;
    }
    virtual void fun2()//重写B中的虚函数
    {
        cout<<"D::fun2()"<<endl;
    }
    virtual void fun4()//D中的虚函数
    {
        cout<<"D::fun4()"<<endl;
    }

public:
    int _d;
};

typedef void(*FUNC)();

void PrintVTable(int* VTable)
{
    cout<<"VTable: "<<VTable<<endl;
    for(int i=0; VTable[i] != 0; ++i)
    {
        printf("VTable[%d]:0x%x,->",i,VTable[i]);
        FUNC f = (FUNC)VTable[i];
        f();
    }
    cout<<endl;
}

int main()
{
    D d;
    d.B::_a = 1;
    d._b = 2;
    d.C::_a = 3;
    d._c = 4;
    d._d = 5;
    int* vtable = (int*)(*(int*)&d);
    PrintVTable(vtable);

    vtable = (int*)(*((int*)&d+sizeof(B)/4));
    PrintVTable(vtable);

    return 0;
}

这里写图片描述

总结:D中的虚函数放在第一个继承基类的虚函数表中,B中会放D中重写的虚函数和自己的虚函数,C中会放D中重写的虚函数和自己的虚函数。

菱形虚拟继承**

//菱形虚拟继承的多态对象模型
class A
{
public:
    virtual void fun1()
    {
        cout<<"A::fun1()"<<endl;
    }
public:
    int _a;
};

class B : virtual public A
{
public:
    virtual void fun1()
    {
        cout<<"B::fun1()"<<endl;
    }
    virtual void fun2()
    {
        cout<<"B::fun2()"<<endl;
    }

public:
    int _b;
};

class C : virtual public A
{
public:
    virtual void fun1()
    {
        cout<<"C::fun1()"<<endl;
    }
    virtual void fun3()
    {
        cout<<"C::fun3()"<<endl;
    }

public:
    int _c;
};

class D : public B,public C
{
public:
    virtual void fun1()//重写B,C中的虚函数
    {
        cout<<"D::fun1()"<<endl;
    }
    virtual void fun2()//重写B中的虚函数
    {
        cout<<"D::fun2()"<<endl;
    }
    virtual void fun4()//D中的虚函数
    {
        cout<<"D::fun4()"<<endl;
    }

public:
    int _d;
};

typedef void(*FUNC)();

void PrintVTable(int* VTable)
{
    cout<<"VTable: "<<VTable<<endl;
    for(int i=0; VTable[i] != 0; ++i)
    {
        printf("VTable[%d]:0x%x,->",i,VTable[i]);
        FUNC f = (FUNC)VTable[i];
        f();
    }
    cout<<endl;
}

int main()
{
    D d;
    d._a = 1;
    d._b = 2;
    d._c = 4;
    d._d = 5;
    int* vtable = (int*)(*(int*)&d);//B的虚函数表
    PrintVTable(vtable);

    vtable = (int*)(*((int*)&d+3));//C的虚函数表
    PrintVTable(vtable);

    vtable = (int*)(*((int*)&d+7));//A的虚函数表
    PrintVTable(vtable);
    return 0;
}

这里写图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值