虚函数表存放在哪里

虚函数表的特征
  • 虚函数表是全局共享的元素, 全局仅有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) ,也就是内存模型中的代码区

参考:

虚函数表存放在哪里

虚函数深入探索

相关推荐

  1. C++ 函数

    2024-07-20 07:38:05       42 阅读
  2. Windows下如何确定函数函数中的位置

    2024-07-20 07:38:05       36 阅读
  3. c++ | 动态编译|函数函数

    2024-07-20 07:38:05       27 阅读
  4. [c/c++] 关于函数

    2024-07-20 07:38:05       53 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-20 07:38:05       52 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-20 07:38:05       54 阅读
  3. 在Django里面运行非项目文件

    2024-07-20 07:38:05       45 阅读
  4. Python语言-面向对象

    2024-07-20 07:38:05       55 阅读

热门阅读

  1. Apache Kylin

    2024-07-20 07:38:05       12 阅读
  2. HTTP状态码(HTTP Status Code)讲解

    2024-07-20 07:38:05       17 阅读
  3. [MAUI 项目实战] 笔记App(二):数据库设计

    2024-07-20 07:38:05       18 阅读
  4. Ruby 循环

    2024-07-20 07:38:05       16 阅读
  5. [React]利用Webcomponent封装React组件

    2024-07-20 07:38:05       12 阅读
  6. CSS3 教程

    2024-07-20 07:38:05       14 阅读
  7. [python] 利用opencv显示对比试验效果

    2024-07-20 07:38:05       13 阅读
  8. vue中的some方法使用@1@

    2024-07-20 07:38:05       14 阅读