《C++多态的对象模型之单/多继承、菱形/菱形虚拟继承》

多态:

多态的两个必要条件:①子类中必须重写父类中的虚函数。②父类的引用/指针依据指向的不同对象(父类或者子类)来调用不同的虚函数。即:父类的指针或引用指向父类时,调用父类的虚函数。父类的指针或引用指向子类时,调用子类的虚函数。


多态的单/多继承对象模型:

单继承:

//单继承

#include<iostream>
using namespace std;

typedef void(*VFPTR)();//VFPTR-->函数指针。

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

class B :public A
{
public:
    virtual void fun1()//virtual可写可不写
    {                 //,因为fun1()在子类中仍然保持虚函数特性。
        cout << "virtual void B::fun1()" << endl;
    }
    virtual void fun2()
    {
        cout << "virtual void B::fun2()" << endl;
    }
public:
    int _b;
};

void PrintVfptr(VFPTR* pvfptr)//形参为指向函数指针的指针,
{                            //此函数功能为:打印虚表中存储的函数指针,并调用该函数。
    size_t i = 0;
    printf("虚表地址:%p\n", pvfptr);
    while (pvfptr[i] != 0)
    {
        printf("第%d个虚函数地址为:%p-->", i + 1, pvfptr[i]);
        pvfptr[i]();
        i++;
    }
}
int main()
{
    B b;
    b._a = 1;
    b._b = 2;
    PrintVfptr((VFPTR*)(*((int*)&b)));
    return 0;
}

这里写图片描述

多继承:

//多继承

#include<iostream>
using namespace std;


typedef void(*VFPTR)();//VFPTR-->函数指针。

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

class B 
{
public:
    virtual void fun1()
    {                 
        cout << "virtual void B::fun1()" << endl;
    }
    virtual void fun3()
    {
        cout << "virtual void B::fun3()" << endl;
    }
public:
    int _b;
};

class C:public A,public B
{
public:
    virtual void fun1()
    {
        cout << "virtual void C::fun1()" << endl;
    }
    virtual void fun4()
    {
        cout << "virtual void C::fun4()" << endl;
    }
public:
    int _c;
};

void PrintVfptr(VFPTR* pvfptr)
{                            
    size_t i = 0;
    printf("虚表地址:%p\n", pvfptr);
    while (pvfptr[i] != 0)
    {
        printf("第%d个虚函数地址为:%p-->", i + 1, pvfptr[i]);
        pvfptr[i]();
        i++;
    }
}


int main()
{
    C c;
    c._a = 1;
    c._b = 2;
    c._c = 3;
    PrintVfptr((VFPTR*)(*((int*)&c)));
    PrintVfptr((VFPTR*)(*((int*)((char*)&c + sizeof(A)))));
    return 0;
}

这里写图片描述


多态的菱形/菱形虚拟继承对象模型:

菱形继承:

//菱形继承


#include<iostream>
using namespace std;


typedef void(*VFPTR)();//VFPTR-->函数指针。

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

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

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

class D :public B,public C
{
public:
    virtual void fun1()
    {
        cout << "virtual void D::fun1()" << endl;
    }
    virtual void fun5()
    {
        cout << "virtual void D::fun5()" << endl;
    }
public:
    int _d;
};
void PrintVfptr(VFPTR* pvfptr)//形参为指向函数指针的指针,
{                            //此函数功能为:打印虚表中存储的函数指针,并调用该函数。
    size_t i = 0;
    printf("虚表地址:%p\n", pvfptr);
    while (pvfptr[i] != 0)
    {
        printf("第%d个虚函数地址为:%p-->", i + 1, pvfptr[i]);
        pvfptr[i]();
        i++;
    }
}


int main()
{
    D d;
    d.B::_a = 1;
    d.C::_a = 2;
    d._b = 3;
    d._c = 4;
    d._d = 5;
    PrintVfptr((VFPTR*)(*((int*)&d)));
    PrintVfptr((VFPTR*)(*((int*)((char*)&d + sizeof(B)))));
    return 0;
}

这里写图片描述

菱形虚拟继承:

//菱形虚拟继承

#include<iostream>
using namespace std;

typedef void(*VFPTR)();//VFPTR-->函数指针。

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

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

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

class D :public B, public C
{
public:
    virtual void fun1()
    {
        cout << "virtual void D::fun1()" << endl;
    }
    virtual void fun5()
    {
        cout << "virtual void D::fun5()" << endl;
    }
public:
    int _d;
};
void PrintVfptr(VFPTR* pvfptr)//形参为指向函数指针的指针,
{                            //此函数功能为:打印虚表中存储的函数指针,并调用该函数。
    size_t i = 0;
    printf("虚表地址:%p\n", pvfptr);
    while (pvfptr[i] != 0)
    {
        printf("第%d个虚函数地址为:%p-->", i + 1, pvfptr[i]);
        pvfptr[i]();
        i++;
    }
}

int main()
{
    D d;
    d._a = 1;
    d._b = 2;
    d._c = 3;
    d._d = 4;
    int size_A = sizeof(A);
    cout << "size_A = " << size_A << endl;
    int size_B = sizeof(B);
    cout << "size_B = " << size_B << endl;
    int size_C = sizeof(C);
    cout << "size_C = " << size_C << endl;
    int size_D = sizeof(D);
    cout << "size_D = " << size_D << endl;
    PrintVfptr((VFPTR*)(*((int*)&d)));
    PrintVfptr((VFPTR*)(*((int*)((char*)&d + (size_B - size_A)))));
    PrintVfptr((VFPTR*)(*((int*)((char*)&d + (size_D - size_A)))));
    return 0;
}

这里写图片描述

总结:
菱形的虚拟继承为单/多继承对象模型、虚拟继承对象模型的综合。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值