C++ 继承时虚函数列表指向函数测试

直接上结论:

1、同一个类的所有对象,共用一个虚函数列表

2、父类和子类都分别有自己的虚函数列表数组

3、子类如果没有改写父类的虚函数,则父类和子类虚函数列表中的代表这个函数的那一项指向同一个函数。

图示:

测试代码及结论:

mytestclass.h:

#ifndef MYTESTCLASS_H
#define MYTESTCLASS_H

class MyTestClass
{
public:
    int weight;
    int age;
    virtual void eat();
    virtual void hh();

    MyTestClass();
};

#endif // MYTESTCLASS_H

mytestclass.cpp:

#include "mytestclass.h"
#include "QDebug"

MyTestClass::MyTestClass()
{

}

void MyTestClass::eat()
{
    qDebug() << "my eat";
}

void MyTestClass::hh()
{
    qDebug() << "my hh";
}

mytestclass2.h

#ifndef MYTESTCLASS2_H
#define MYTESTCLASS2_H
#include "mytestclass.h"


class MyTestClass2 : public MyTestClass
{
public:
    int weight2;
    virtual void eat();
    
    MyTestClass2();
};

#endif // MYTESTCLASS2_H

mytestclass2.cpp

#include "mytestclass2.h"
#include "QDebug"

MyTestClass2::MyTestClass2()
{

}

void MyTestClass2::eat()
{
    qDebug() << "my2 eat";
}

main.cpp

#include "mytestclass.h"
#include "mytestclass2.h"
#include <QApplication>
typedef void(* fun_p)(void);

void Test_virtualFunc()
{

    MyTestClass *pmyTestObj = new MyTestClass();
    MyTestClass2 *pmyTestObj2 = new MyTestClass2();
    MyTestClass2 *pmyTestObj3 = new MyTestClass2();

    pmyTestObj->weight = 10;
    pmyTestObj->age = 100;
    pmyTestObj2->weight = 20;
    pmyTestObj2->age = 200;
    pmyTestObj2->weight2 = 2000;
    pmyTestObj3->weight = 30;
    pmyTestObj3->age = 300;
    pmyTestObj3->weight2 = 3000;

    fun_p **func_pp = (fun_p **)pmyTestObj;
    fun_p **func_pp2 = (fun_p **)pmyTestObj2;
    fun_p **func_pp3 = (fun_p **)pmyTestObj3;

    (**func_pp)();
    (**func_pp2)();

    /* 父的地址空间 */
    int *p = (int *)pmyTestObj;
    qDebug() << "father: virtual list addr: " << (int *)*(int *)p;
    p++;
    qDebug() << "father: member1:" << *(int *)p;
    p++;
    qDebug() << "father: member2:" << *(int *)p;

    /* 子1的地址空间 */
    p = (int *)pmyTestObj2;
    qDebug() << "son1: virtual list addr: " << (int *)*(int *)p;
    p++;
    qDebug() << "son1: member1:" << *(int *)p;
    p++;
    qDebug() << "son1: member1:" << *(int *)p;
    p++;
    qDebug() << "son1: member1:" << *(int *)p;

    /* 子2的地址空间 */
    p = (int *)pmyTestObj3;
    qDebug() << "son2: virtual list addr: " << (int *)*(int *)p;
    p++;
    qDebug() << "son2: member1:" << *(int *)p;
    p++;
    qDebug() << "son2: member1:" << *(int *)p;
    p++;
    qDebug() << "son2: member1:" << *(int *)p;

    /* 父虚函数列表存的内容 */
    qDebug() << "father virtual Func1:" << (int *)((*func_pp)[0]);
    qDebug() << "father virtual Func2:" << (int *)((*func_pp)[1]);

    /* 子1虚函数列表存的内容 */
    qDebug() << "son1 virtual Func1:" << (int *)((*func_pp2)[0]);
    qDebug() << "son1 virtual Func2:" << (int *)((*func_pp2)[1]);

    /* 子2虚函数列表存的内容 */
    qDebug() << "son2 virtual Func1:" << (int *)((*func_pp3)[0]);
    qDebug() << "son2 virtual Func2:" << (int *)((*func_pp3)[1]);

}

int main(int argc, char *argv[])
{
    Test_virtualFunc();
    return 0;
}

测试结果:

my eat
my2 eat
father: virtual list addr:  0x409084
father: member1: 10
father: member2: 100
son1: virtual list addr:  0x409094
son1: member1: 20
son1: member1: 200
son1: member1: 2000
son2: virtual list addr:  0x409094
son2: member1: 30
son2: member1: 300
son2: member1: 3000
father virtual Func1: 0x4023d6
father virtual Func2: 0x402458
son1 virtual Func1: 0x4024fc
son1 virtual Func2: 0x402458
son2 virtual Func1: 0x4024fc
son2 virtual Func2: 0x402458

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值