C++虚函数的作用及实现原理(三)(含有虚函数的类的对象模型之多继承)

上一篇https://blog.csdn.net/a15929748502/article/details/80930039中我们已经一起探索了含有虚函数单继承的对象模型,这一讲我们来一起看看多继承时的对象模型。

下面就由我来构造一个含有虚函数的多继承的对象模型

#include <iostream>
using namespace std;

class B1
{
        public :
                int _b1 ;
                virtual void FuncA1()
                {
                        cout << "          ---------->B1::FuncA1 ..." << endl;
                }

                virtual void FuncB1()
                {
                        cout << "          ---------->B1::FuncB1 ..." << endl;
                }
};
class B2
{
        public :
                int _b2 ;
                virtual void FuncA2()
                {
                        cout << "          ---------->B2::FuncA2 ..." << endl;
                }

                virtual void FuncB2()
                {
                        cout << "          ---------->B2::FuncB2 ..." << endl;
                }
};


class D : public B1,public B2
{
        public :
                int _d;
                virtual void FuncB1()
                {
                        cout << "          ---------->D::FuncB1 ..." << endl;
                }
                virtual  void FuncA2()
                {
                        cout<<"            ---------->D::FuncA2 ..."<<endl;
                }
};
typedef  void (*Func)();
int main ()
{
        B1  b1;
        B2  b2;
        D  d;
        b1._b1=1;
        b2._b2=2;
        d._b1=3;
        d._b2=4;
        d._d=5;
        long **p1=(long**)&b1;
        long **p2=(long**)&b2;
        long **pd=(long**)&d;
        cout << "B1" << endl;
        cout <<*((int*)&b1) << endl;
        ((Func)p1[0][0])();
        ((Func)p1[0][1])();
        cout <<*((int*)&b1+1) << endl;
        cout << "sizeof(B1) = " << sizeof(B1) << endl;
        cout <<"---------------------------------------------------------" << endl;
        cout << "B2" << endl;
        cout <<*((int*)&b2) << endl;
        ((Func)p2[0][0])();
        ((Func)p2[0][1])();
        cout <<*((int*)&b2+1) << endl;
        cout << "sizeof(B2) = " << sizeof(B2) << endl;

        cout <<"---------------------------------------------------------" << endl;

        cout << "D" << endl;
        cout <<*((int*)&d) << endl;
        ((Func)pd[0][0])();
        ((Func)pd[0][1])();
        cout <<*((int*)&d+1) << endl;
        cout <<*((int*)&d+2) << endl;
        ((Func)pd[2][0])();
        ((Func)pd[2][1])();
        cout <<*((int*)&d+3) << endl;
        cout <<*((int*)&d+4) << endl;
        cout << "sizeof(D) = " << sizeof(D) << endl;

        return 0;
}

现在我们来打印一下结果

[root@localhost C++]# ./a.out
B1
134516512
          ---------->B1::FuncA1 ...
          ---------->B1::FuncB1 ...
1
sizeof(B1) = 8
---------------------------------------------------------
B2
134516496
          ---------->B2::FuncA2 ...
          ---------->B2::FuncB2 ...
2
sizeof(B2) = 8
---------------------------------------------------------
D
134516456
          ---------->B1::FuncA1 ...
          ---------->D::FuncB1 ...
3
134516476
            ---------->D::FuncA2 ...
          ---------->B2::FuncB2 ...
4
5
sizeof(D) = 20

可以看到派生类D的大小为20个字节,

下面是我画出的对象模型


也就是


不知道大家看懂了没有呢

小小的总结一下:对于多继承来说基类的对象大小:非静态成员大小+4(虚表指针)

派生类的大小:继承的基类数量*4+非静态成员的大小

在基类虚表中:将类中的虚函数按照在类中生命的先后顺序添加在虚表里

而在多继承的派生类之中:(1)将基类虚函数表中的内容拷贝一份,(2)如果派生类重写了基类的某个虚函数,使派生类自己的虚函数替换派生类虚表中相同偏移量位置的基类虚函数(3)按照派生类特有的虚函数的声明次序将其增加到第一张虚函数表的最后

这就是基本多继承下含有虚函数的类的对象模型,下一篇中我会把特殊的多继承菱形继承以及菱形虚拟继承说给你听。



猜你喜欢

转载自blog.csdn.net/a15929748502/article/details/80941931
今日推荐