虚函数表存放在哪里

虚函数表的特征
  • 虚函数表是全局共享的元素, 全局仅有1个, 在编译时构造完成
  • 虚函数表类似一个数组, 类对象中存储vptr指针, 指向虚函数表。即虚函数表不是函数,不是程序代码,所以不可能存储在代码段
  • 虚函数表存储虚函数的地址,也就是说虚函数表的元素是指向类成员函数的指针, 而类中虚函数的个数在编译期就可以确定,所以虚函数表的大小在编译期可以确定的,不必动态分配内存空间存储虚函数表,所以不在堆中

总结: 虚函数表类似于类中的静态成员变量,和静态成员变量一样是全局共享的,属于一个类所有对象的,并不是某一个类特属的, 在linux/unix中 存放在可执行文件的只读数据段中

对于有虚函数或者继承于有虚函数的基类时,对这个类实例化的时候,构造函数执行时会对虚函数表指针vptr进行初始化,gcc和微软的的编译器会将其放在对象内存布局的最前面

有虚函数的类, 改类的大小会增加一个指针的大小(32位系统是4字节, 64位系统是8字节)。

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

class Base {
public:
	virtual void a() { cout << "Base a()" << endl; }
	virtual void b() { cout << "Base b()" << endl; }
	virtual void c() { cout << "Base c()" << endl; }
};

class Derive : public Base {
public:
	virtual void b() { cout << "Derive b()" << endl; }
};

int main()
{
	typedef void (*Func)();
	cout << "-----------Base------------" << endl;
	Base* q = new Base;
	long* tmp1 = (long*)q;
	long* vptr1 = (long*)(*tmp1);
	for (int i = 0; i < 3; i++) {
		printf("vptr[%d] : %p\n", i, vptr1[i]);
	}
	Func a = (Func)vptr1[0];
	Func b = (Func)vptr1[1];
	Func c = (Func)vptr1[2];
	a();
	b();
	c();

	Derive* p = new Derive;
	long* tmp = (long*)p;
	long* vptr = (long*)(*tmp);
	cout << "---------Derive------------" << endl;
	for (int i = 0; i < 3; i++) {
		printf("vptr[%d] : %p\n", i, vptr[i]);
	}
	Func d = (Func)vptr[0];
	Func e = (Func)vptr[1];
	Func f = (Func)vptr[2];
	d();
	e();
	f();

	
	return 0;
}

多重继承

多重继承的派生类, 会包含多个虚函数指针。

注意,派生类将自己的虚函数放在base1的虚函数表后面

在这里插入图片描述

虚函数表在编译时期创建, 而虚函数指针是在对象实例化时候创建(调用构造函数时), 所以 **虚函数指针在运行时创建 ** , 将该类虚函数表的地址赋值给对象的虚函数指针。

一般分为五个区域: 栈区, 堆区,函数区(存放函数体等二进制代码), 全局静态区, 常量区。

所以C++中虚函数表 位于只读数据段(.rodata), 也就是C++模型中的常量区, 而虚函数则位于代码段(.text) ,也就是内存模型中的代码区

参考:

虚函数表存放在哪里

虚函数深入探索

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吃肉夹馍不要夹馍

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值