【C++】【面向对象】虚函数表和虚函数表指针

背景

virtual装饰类的成员方法来实现动态继承的媒介(虚函数表和虚函数指针)。

虚函数表

  • 什么时候生成?
    编译器编译的时候生成,virutal关键字修饰的函数
  • 存放在哪里?
    可执行程序(磁盘)和运行状态(内存)。
    磁盘:.rodata下面还有一个.text(存储代码段)
    在这里插入图片描述
    内存:会将磁盘对应的空间装填到内存对应的空间上,此时的虚函数表是以存储虚函数地址的数组进行存储,每一个虚函数地址指向每个虚函数的具体代码位置。
    在这里插入图片描述

虚函数表与虚函数表指针之间的关系

访问虚函数表便是虚函数指针的功能。当一个含有虚函数的类被实例化为对象时,便会为该对象生成一个虚函数指针vtptr。一般而言,类的不同对象所生成的虚函数表指针的指向是不一样的。由于虚函数表指针是对象的潜在成员,需要通过深拷贝(如拷贝构造/重载赋值运算符)来避免多个指针指向同一个地址,若一个指针释放该地址导致其余指针发生错误的问题。

虚函数表指针

虚函数表指针的创建时机:

  • 类对象构造时候,把类的虚函数表地址赋值给vptr
  • 没有构造函数,编译器会生成默认的构造函数
  • 在继承情况下,虚函数指针赋值过程:
    • 对于基类对象,虚表指针指向基类的虚表。
    • 对于派生类对象,当基类的构造函数执行时,虚表指针先被设置为基类的虚表,然后在派生类构造函数执行前被更新为派生类的虚表。

tips:每一个对象的虚表指针在对象的最开始地方。

class A{
public:
	int x;
};
class B{
public:
	int x;
	virtual void func(){};
}
int main(){
	A a;
	B b;
	std::cout << sizeof(a) << std::endl; //可能为1
	std::cout << sizeof(b) << std::endl; //可能为8,a与b的大小会差一个虚函数表的大小
	A* ptra = &a;
	B* ptrb = &b;
	std::cout << reinterpret_cast<void*>(ptra) <<endl;
	std::cout << &a.x << std::endl;
	std::cout << reinterpret_cast<void*>(ptrb) <<endl;
	std::cout << &b.x << std::endl;
	//从后4个打印可以看出来,尤其是a和b的打印可看出,虚函数表的位置
	return 0;
}

(后续会补充…)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值