【C++】多态 ⑧ ( 验证指向 虚函数表 的 vptr 指针 | 对比定义了虚函数的类和没有定义虚函数类的大小 )
  K1I6GvxBEuyy 2023年12月02日 17 0



文章目录

  • 一、验证指向 虚函数表 的 vptr 指针 是否存在
  • 1、虚函数表与 vptr 指针由来
  • 2、虚函数类与普通函数类对比 - 多出了 vptr 指针的大小




对比 定义了 虚函数 的类 与 没有定义虚函数的类 的大小 , 其它成员都相同 , 定义了虚函数的类多出了 4 字节 , 多出的 4 字节就是 vptr 指针占用的内存空间 ;






一、验证指向 虚函数表 的 vptr 指针 是否存在




1、虚函数表与 vptr 指针由来



" 虚函数表 " 由 C++ 编译器 负责 创建 与 维护 , 被 virtual 关键字 修饰的 虚函数 , 会自动 被 C++ 编译器 存储到 " 虚函数表 " 中 ;



虚函数表 创建 : 在 类 中使用 virtual 关键字 声明 虚函数 时 , C++ 编译器 会自动为该类生成 " 虚函数表 " ;

  • 生成虚函数表的前提是 至少有 1 个虚函数 ;
  • 如果 没有虚函数 , 就不会生成虚函数表 ;
  • 如果 类 中有 virtual 虚函数 , 则 该类的 每个对象 中 , 都有一个 指向 虚函数表的 vptr 指针 ;


虚函数表 存储 虚函数指针 : " 虚函数表 " 是 存储 " 类成员函数指针 " 的 数据结构 , 是一个 函数指针数组 , 数组中的元素都是函数指针 , 具体存储的都是 指向 类中的虚函数 的指针 ;

  • 如果 子类 中 , 重写了 父类的 virtual 虚函数 , 那么 C++ 编译器会在 子类 虚函数表 中放入该 子类虚函数的 函数指针 ;

如果 C++ 类中存在 virtual 虚函数 , 在创建对象时 , 会生成 虚函数表 Virtual Function Table , 简称 vtable ;

C++ 编译器 编译 代码时 , 会自动为该类 添加 一个 vptr 指针 成员变量 , 该指针 会指向 虚函数表 ;



2、虚函数类与普通函数类对比 - 多出了 vptr 指针的大小



下面的代码中 , 定义了 2 个类 , 区别是 一个定义了 virtual 虚函数 , 另外一个没有定义 虚函数 ;

  • 在 Parent 中定义了 虚函数 virtual void fun(int a) ;
  • 在 Parent2 中定义的是 普通函数 void fun(int a) ;

使用 sizeof 函数 , 获取这两个类的大小 , 判断两个类的区别 ;

最终得到 , 有 虚函数 的 类 , 比 没有 虚函数 的 类 , 多 4 字节 , 也就是一个指针的大小 ,

定义了 虚函数 的类 , 多出的 4 字节就是 vptr 指针的大小 ;



代码示例 :

#include "iostream"
using namespace std;

// 父类
class Parent {
public:
	virtual void fun(int a)
	{
		cout << "执行 父类 Parent 的 virtual void fun(int a) 函数" << endl;
	}
	int a;
};

// 父类
class Parent2 {
public:
	void fun(int a)
	{
		cout << "执行 父类 Parent2 的 void fun(int a) 函数" << endl;
	}
	int a;
};

// 子类
class Child : public Parent {
public:
	virtual void fun(int a)
	{
		cout << "执行 子类 virtual void fun(int a) 函数" << endl;
	}
};

int main() {

	Parent* p;
	// 创建 Child 子类对象时
	// 发现有 virtual 虚函数 会创建 虚函数表
	// 在对象中使用 vptr 指针指向 虚函数表 首地址
	Child c;

	// 将父类指针指向子类对象
	p = &c;
	// 通过父类指针调用子类对象的 fun 函数
	p->fun(1);

	// 打印 Parent 的 大小
	cout << "sizeof(Parent) : " << sizeof(Parent) << endl;

	// 打印 Parent2 的 大小
	cout << "sizeof(Parent2) : " << sizeof(Parent2) << endl;

	// 控制台暂停 , 按任意键继续向后执行
	system("pause");

	return 0;
}

执行结果 :

执行 子类 virtual void fun(int a) 函数
sizeof(Parent) : 8
sizeof(Parent2) : 4
Press any key to continue . . .

【C++】多态 ⑧ ( 验证指向 虚函数表 的 vptr 指针 | 对比定义了虚函数的类和没有定义虚函数类的大小 )_开发语言


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年12月02日 0

暂无评论

推荐阅读
K1I6GvxBEuyy
作者其他文章 更多