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

这篇具有很好参考价值的文章主要介绍了【C++】多态 ⑧ ( 验证指向 虚函数表 的 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 指针 | 对比定义了虚函数的类和没有定义虚函数类的大小 ),C++,c++,开发语言,vptr指针,虚函数表,多态,原力计划文章来源地址https://www.toymoban.com/news/detail-735371.html

到了这里,关于【C++】多态 ⑧ ( 验证指向 虚函数表 的 vptr 指针 | 对比定义了虚函数的类和没有定义虚函数类的大小 )的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++笔记之基类指针动态地指向某一个子类情况列举

    code review!

    2024年02月12日
    浏览(48)
  • 【C++】结构体 - 定义和使用,结构体数组,结构体指针,结构体嵌套结构体,结构体做函数参数,结构体 const

    结构体属于用户自定义的数据类型,允许用户存储不同的数据类型。 struct 结构体 {结构体成员列表}; 通过结构体创建变量的方法有三种: struct 结构体名 变量名 struct 结构体名 变量名 = {成员1值, 成员2值, …} 定义结构体时顺便创建变量 总结三点: 定义结构体时的是

    2024年02月07日
    浏览(55)
  • 【C++漂流记】结构体的定义和使用、结构体数组、结构体指针、结构体做函数参数以及结构体中const的使用

    结构体(struct)是C语言中一种重要的数据类型,它由一组不同类型的成员组成。结构体可以用来表示一个复杂的数据结构,比如一个学生的信息、一个员工记录或者一个矩形的尺寸等。 结构体定义后,可以声明结构体变量,每个结构体变量包含结构体类型的所有成员。结构

    2024年02月09日
    浏览(43)
  • <c++>虚函数与多态 | 虚函数与纯虚函数 | 多态的实现原理 | 虚析构函数

    🚀 个人简介:CSDN「 博客新星 」TOP 10 , C/C++ 领域新星创作者 💟 作    者: 锡兰_CC ❣️ 📝 专    栏: 从零开始的 c++ 之旅 🌈 若有帮助,还请 关注➕点赞➕收藏 ,不行的话我再努努力💪💪💪 在上一篇文章中,我们介绍了 c++ 中类与对象的继承,继承可以根据一个或

    2023年04月18日
    浏览(39)
  • 【C++初阶(三)】引用详解(对比指针)

    💓博主CSDN主页:杭电码农-NEO💓   ⏩专栏分类:C++初阶之路⏪   🚚代码仓库:NEO的学习日记🚚   🌹关注我🫵带你学习排序知识   🔝🔝 C语言中有一利器: 指针 而C++中增加了另一利器: 引用 这两个板块的存在 极大了提升了C/C++的可用性! 本篇文章将给大家详细讲解引用 并

    2024年02月12日
    浏览(49)
  • c、c++、java、python、js对比【面向对象、过程;解释、编译语言;封装、继承、多态】

    目录 内存管理、适用 区别 C 手动内存管理:C语言没有内置的安全检查机制,容易出现内存泄漏、缓冲区溢出等安全问题。 适用于系统级编程 C++ 手动内存管理:C++需要程序员手动管理内存,包括分配和释放内存,这可能导致内存泄漏和指针错误。 适用于游戏引擎和系统级编

    2024年02月08日
    浏览(75)
  • C++修炼之路之多态---多态的原理(虚函数表)

    目录 一:多态的原理  1.虚函数表  2.原理分析 3.对于虚表存在哪里的探讨 4.对于是不是所有的虚函数都要存进虚函数表的探讨 二:多继承中的虚函数表 三:常见的问答题  接下来的日子会顺顺利利,万事胜意,生活明朗-----------林辞忧  接上篇的多态的介绍后,接下来介绍

    2024年04月26日
    浏览(43)
  • 【C++】虚函数与多态

    多态性是面向对象程序设计的重要特征之一,是指发出同样的消息被不同类型的对象接受时有可能导致完全不同的行为。多态的实现:函数重载、运算符重载、模板、虚函数。 静态绑定:绑定过程出现在编译阶段,在编译期就已经确定要调用的函数。 动态绑定:绑定过程工

    2024年02月10日
    浏览(47)
  • C语言:指向数组的指针和指向数组首元素的指针

    相关阅读 C语言 https://blog.csdn.net/weixin_45791458/category_12423166.html?spm=1001.2014.3001.5482         指向数组的指针和指向数组首元素的指针常常被混淆,或者笼统地被称为数组指针,但它们之间是有差别的,本文就将对此进行讨论。         下面的代码首先创建了一个数组,然后创

    2024年02月02日
    浏览(51)
  • [C++] 多态(上) -- 抽象类、虚函数、虚函数表

    通俗来说,多态就是多种形态, 具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态。 举个栗子:比如 买票这个行为: 当 普通人 买票时,是全价买票; 学生 买票时,是半价买票; 军人 买票时是优先买票。 这个例子就是多态,不同身份对应不同的票

    2024年02月04日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包