虚函数表分析(单继承情况和多继承情况)

单继承:

#include<iostream>
#include<stdio.h>
using namespace std;

class A
{
public:
    virtual void x() {cout<<"x()"<<endl;}
    virtual void y() {cout<<"y()"<<endl;}
    virtual void z() {cout<<"z()"<<endl;}
};

class B:public A
{
public:
    virtual void y() {cout<<"B::y()"<<endl;}
};
int main(void)
{
    
    B b;
    A a = b;

    long *p1=(long*)&a;
    long *p2=(long*)*p1;

    typedef void (*p)(void);

    p f1 = (p)(*p2);
    p f2 = (p)(*(p2+1));
    p f3 = (p)(*(p2+2));

    f1();
    f2();
    f3();
    return 0;
}

多继承:

#include<iostream>
#include<stdio.h>
using namespace std;

class A1
{
public:
    virtual void x() {cout<<"A1::x()"<<endl;}
    virtual void y() {cout<<"A1::y()"<<endl;}
    virtual void z() {cout<<"A1::z()"<<endl;}
};

class A2
{
public:
    virtual void x() {cout<<"A2::x()"<<endl;}
    virtual void y() {cout<<"A2::y()"<<endl;}
    virtual void z() {cout<<"A2::z()"<<endl;}
};

class B:public A1,public A2
{
public:
    virtual void y() {cout<<"B::y()"<<endl;}
};

int main(void)
{
    int i,j,k;
    i=sizeof(A1);
    j=sizeof(A2);
    k=sizeof(B);
    cout<<i<<  j<<  k<<endl;//输出结果可以看出,多重继承情况下,子类有多个虚函数表指针,分别指向各自的虚函数表

    B b;
    long *p1=(long*)&b;
    long *p2=(long*)*p1;//取第一个虚函数表指针

    long *p3=(long*)*(p1+1);//取第二个虚函数表指针

    //定义一个函数指针,形参类型为void
    typedef void(*p)(void);

    //指向第一个虚函数表的各自的虚函数,因为只有3个虚函数,所以这里只加到了2,继续往下加指向的内容不确定
    p f1= (p)*p2;
    p f2= (p)*(p2+1);
    p f3= (p)*(p2+2);
    
    //指向第二个虚函数表的各自的虚函数
    p f4= (p)*p3;
    p f5= (p)*(p3+1);
    p f6= (p)*(p3+2);

    //函数调用
    f1();
    f2();
    f3();

    f4();
    f5();
    f6();

    return 0;
}

运行结果:
在这里插入图片描述
总结:
(1)一个类只有虚函数才会存在虚函数表,同属于一个类的对象共享虚函数表,但是有各自的虚函数表指针(当然,这个内容是相同的)
(2)父类中有虚函数表,则子类中一定有虚函数表
(3)多重继承情况下,子类有多个虚函数表指针,虚函数表指针的位置取决于继承顺序
(4)如果子类中没有新的虚函数,则可以认为子类的虚函数表和父类的虚函数表内容相同。
(5)超出虚函数表部分的内容不可知。

猜你喜欢

转载自blog.csdn.net/qq_38158479/article/details/106967436