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

来源:互联网 发布:javascript静态网页 编辑:程序博客网 时间:2024/05/22 06:24

多态:

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


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

单继承:

//单继承#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;}

这里写图片描述

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

原创粉丝点击