c++_vbptr和vfptr

虚基表

#include<iostream>

class Base
{
public:
	char m_base1;
	char m_base2;
	Base(int a) : m_base1(a),m_base2(a){}
};

class Child : virtual public Base
{
public:
	char m_child;
	Child(int a,int b) : Base(a),m_child(b){}
};

int main()
{
	Child c(1,2);
	std::cout << sizeof(Base) << std::endl;
	std::cout << sizeof(Child) << std::endl;
}
/*
2
10
*/

这里如果是64位编译的话,则输出2,24,也就是说64位会对齐。

调试,查看内存&c

0x0105FDE4  30 8b f4 00 02 cc cc cc  
0x0105FDEC  01 01 cc cc cc cc cc cc
00F48B30 00 00 
00F48B32 00 00 
00F48B34 08 00 
00F48B36 00 00 
00F48B38 00 00
00F48B3A 00 00

使用vs命令行进入cpp路径,cl main.cpp /d1 reportSingleClassLayoutChild

class Child     size(10):
        +---
 0      | {vbptr}
 4      | m_child
        | <alignment member> (size=3)
        +---
        +--- (virtual base Base)
 8      | m_base1
 9      | m_base2
        +---

Child::$vbtable@:
 0      | 0
 1      | 8 (Childd(Child+0)Base)
vbi:       class  offset o.vbptr  o.vbte fVtorDisp
            Base       8       0       4 0

o.vbte,fVtorDisp暂不知道什么意思。

虚函数表

下面是引入虚函数的代码。

#include<iostream>

class Base
{
public:
	char m_base;
	Base(char a) : m_base(a){}
	virtual void func(){}

};

class Child : virtual public Base
{
public:
	char m_child;
	Child(char a,char b) : Base(a),m_child(b){}
	virtual void func() 
	{
	    std::cout << "child func()" << std::endl;
	}
};

char main()
{
	Child c(1,2);
	std::cout << sizeof(Base) << std::endl;
	std::cout << sizeof(Child) << std::endl;
}
/*
8
20
*/

调试查看&c

0x0135F8A0  40 6b 3c 00 02 cc cc cc  @k<..???
0x0135F8A8  00 00 00 00 3c 6b 3c 00  ....<k<.
0x0135F8B0  01 cc cc cc

后8个字节为父类数据,0x3c6b3c为虚函数表地址。

这是虚继承特有的结构,共享父类的虚函数表指针;如果不是虚继承,那么子类会有自己的虚函数表指针。

下面是虚基表,前4个字节是相对本对象的偏移,0x0000000c是父类数据相对偏移。

003C6B40 00 00 
003C6B42 00 00 
003C6B44 0C 00 
003C6B46 00 00 

显式调用

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

class Base1
{
public:
	int a = 0x11111111;
	virtual void func1(){}
	virtual void func2(){}
};



class Child : public Base1
{
public:
	virtual void func1() 
	{
		cout << "1" << endl;
	}
	virtual void func2()
	{
		cout << "2" << endl;
	}
};

typedef void (*PFUN)();

int main(int argc, char *argv[])
{
	Child c;

	PFUN *pvtable = (PFUN*)*(PFUN*)&c;
	PFUN pfun = (PFUN)pvtable[0];
	pfun();
	pfun = (PFUN)pvtable[1];
	pfun();
	cin.get();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值