C++面试常见问题多态如何实现?虚函数的底层如何实现?

news2024/9/27 17:29:47

1.黑马程序员多态例子

class Animal
{
public:
	//Speak函数就是虚函数
	//函数前面加上virtual关键字,变成虚函数,那么编译器在编译的时候就不能确定函数调用了。
	virtual void speak()
	{
		cout << "动物在说话" << endl;
	}
};

class Cat :public Animal
{
public:
	void speak()
	{
		cout << "小猫在说话" << endl;
	}
};

class Dog :public Animal
{
public:

	void speak()
	{
		cout << "小狗在说话" << endl;
	}

};
//我们希望传入什么对象,那么就调用什么对象的函数
//如果函数地址在编译阶段就能确定,那么静态联编
//如果函数地址在运行阶段才能确定,就是动态联编

void DoSpeak(Animal & animal)
{
	animal.speak();
}
//
//多态满足条件: 
//1、有继承关系
//2、子类重写父类中的虚函数
//多态使用:
//父类指针或引用指向子类对象

void test01()
{
	Cat cat;
	DoSpeak(cat);


	Dog dog;
	DoSpeak(dog);
}


int main() {

	test01();

	system("pause");

	return 0;
}
```


2.多态分为两类

* 静态多态: 函数重载 和 运算符重载属于静态多态,复用函数名
* 动态多态: 派生类和虚函数实现运行时多态

静态多态和动态多态区别:

* 静态多态的函数地址早绑定  -  编译阶段确定函数地址
* 动态多态的函数地址晚绑定  -  运行阶段确定函数地址

早绑定--即编译阶段可确定函数地址   

晚绑定--根据函数传递的参数确定调用什么函数  只有在运行时才可以确定(传猫,猫叫;传狗,狗叫)

3.多态满足条件

* 有继承关系
* 子类重写父类中的虚函数

重载与重写区别:重载--函数名相同 参数不同  ;重写--函数名,返回值类型,参数列表全都相同

4.多态使用条件

* 父类指针或引用指向子类对象

5.多态原理

class Animal
{
public:
	virtual void speak()
	{
		cout << "动物在说话" << endl;
	}
};

统计animal类占多少内存空间

 

 sizeof Animal =1         加上virtual之后       sizeof Animal =4; 

原因  :类内部多了指针   vfptr(virtual function pointer)虚函数(表)指针 

 vfptr指向vftabel(虚函数表)

虚函数表:表内记录 虚函数入口地址

1.父类

2.单继承   

子类继承与父类完全相同内容

3.当子类重写父类虚函数 

子类中虚函数表内部 替换成子类虚函数地址

4.当父类指针或引用指向子类对象时 ,发生多态

6.总结

1.虚函数是什么 

   在语法上, 成员函数之前加virtual关键字就让这个函数变成虚函数

   虚函数的作用是实现多态性,即通过基类访问派生类的函数

2.什么是纯虚函数

在虚函数后面添加 =0 ,虚函数就成为纯虚函数,

在很多情况下,基类生成对象很不合理。为了解决这个问题,引入了纯虚函数的概念,将函数定义为纯虚函数,派生类中必须重写实现纯虚函数。对于实现了纯虚函数的子类,该纯虚函数在子类中就变成了虚函数

3.虚函数和纯虚函数区别

  • 虚函数定义形式:成员函数前添加 virtual 关键字,纯虚函数在虚函数后添加 =0 ;
  • 含有纯虚函数的类,称为抽象类;只含有虚函数的类,不能称为抽象类。
  • 虚函数既可以直接使用,也可以被子类重载实现后,以多态的形式调用;而纯虚函数必须被子类重写实现,才能以多态的形式调用,因为纯虚函数在基类中只有声明。否则子类也是抽象类不可实例化
  • 无论虚函数还是纯虚函数,定义中都不能有 static 关键字。因为 static 关键字修饰的内容在编译前就要确定,而虚函数、纯虚函数是在运行时动态绑定的。

4.虚函数表是什么

虚函数表是一个存储着虚函数地址的数据结构;表内记录着虚函数入口地址

5.虚函数表指针是什么

虚函数表指针指向虚函数表;

虚函数的调用是通过查虚函数表来进行的 ;虚函数表中进行查找,则是通过虚指针来调用;

6.虚函数表以及虚函数指针分别是在什么时候创建的

虚函数表的初始化在编译时期,而虚指针的初始化是在构造函数里完成的,而子类虚指针的指向并不是一来就指向子类的那个虚函数表,因为我们都知道子类在调用构造函数时会先调用父类构造函数,这时候虚指针还是指向父类的那个虚表,而当调用子类的构造函数时又会将指向改变为子类的那块表,这就是为什么在父类构造函数里调用虚函数并不能实现多态的原因

内容源自黑马视频以及网络博客总结

54 类和对象-多态-多态的原理剖析_哔哩哔哩_bilibili

C++面向对象总结:虚指针与虚函数表,干货又来了 - 知乎 (zhihu.com)

什么是虚函数?什么是纯虚函数?两者有什么区别?_虚函数和纯虚函数的区别_爱吃煎饺的LinV的博客-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1130573.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Jetpack:016-Jetpack中的SanckBar

文章目录 1. 概念介绍2. 使用方法2.1 显示内容2.2 显示方法 3. 示例代码4. 内容总结 我们在上一章回中介绍了Jetpack相关的概念和主要内容&#xff0c;本章回中主要介绍 SnackBar。闲话休提&#xff0c;让我们一起Talk Android Jetpack吧&#xff01; 1. 概念介绍 我们在本章…

【J-Long Group Limited】申请1500万美元纳斯达克IPO上市

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 猛兽财经获悉&#xff0c;总部位于中国香港的J-Long Group Limited&#xff08;简称&#xff1a;J-Long&#xff09;近期已向美国证券交易委员会&#xff08;SEC&#xff09;提交招股书&#xff0c;申请在纳斯达克IPO上市&…

C语言 每日一题 PTA 10.21-10.24日 day3

1.计算分段函数[1] 本题目要求计算下列分段函数f(x)的值&#xff1a; yf(x)1/x x!0 yf(x)0 x0 int main() {double num 0;scanf("%lf", &num);double result 0;if (num 0){result 0;}else{result 1 / num;}printf("f(%.1lf)%.1lf", num, result)…

获取Android签名文件的MD5和SHA1指纹

以前在App中集成百度地图时&#xff0c;需要在百度地图的开发者网站上绑定应用的包名和签名&#xff0c;以预防自己的key被别人乱用。 最近公司的一个球机产品也搞了类似的做法&#xff0c;我们要访问它的摄像头功能需要使用厂家提供的aar库&#xff0c;但是你要想正常调用它的…

Unity性能优化一本通

文章目录 关于Unity性能优化一、资源部分&#xff1a;1、图片1.1、 图片尺寸越小越好1.2、使用2N次幂大小1.3、取消勾选Read/Write Enabled1.4、图片压缩1.5、禁用多余的Mip Map1.6、合并图集 2、模型2.1.限制模型面数2.2.限制贴图的大小2.3.禁用Read/Write Enables2.4.不勾选其…

阻塞队列BlockingQueue实战及其原理分析

一&#xff0c;队列 1. 队列 是限定在一端进行插入&#xff0c;另一端进行删除的特殊线性表。 允许出队的一端称为队头&#xff0c;允许入队的一端称为队尾。 先进先出(FIFO)线性表。 1.1 Queue接口 2. 阻塞队列&#xff08;BlockingQueue&#xff09; 阻塞队列 (BlockingQueu…

Linux系统64位ATT系统调用汇编指令syscall

相关概念 在Linux中syscall是系统调用&#xff08;英文&#xff1a;system call&#xff09;的指令。 想要深入了解syscall的作用&#xff0c;就需要了解特权级别。 现代计算机通常采用名为保护环&#xff08;Protection Rings&#xff09;的机制来保护整个系统的数据和功能&a…

出海 SaaS 企业增长修炼手册2:Kyligence 落地 PLG 是如何避坑的?

在第一篇文章&#xff08;点击阅读 &#x1f449; 出海 SaaS 企业增长修炼手册&#xff1a;聊聊 PLG 的关键指标、技术栈和挑战&#xff09;中&#xff0c;我们分享了 SaaS 企业在落地 PLG 战略中可能遇到的挑战以及相应的解决方案&#xff0c;今天我们将从 Kyligence 亲身实践…

【数据结构】数组和字符串(二):特殊矩阵的压缩存储:对角矩阵——一维数组

文章目录 4.2.1 矩阵的数组表示4.2.2 特殊矩阵的压缩存储a. 对角矩阵的压缩存储结构体初始化元素设置元素获取打印矩阵主函数输出结果代码整合 4.2.1 矩阵的数组表示 【数据结构】数组和字符串&#xff08;一&#xff09;&#xff1a;矩阵的数组表示 4.2.2 特殊矩阵的压缩存储…

Qt之普通项目如何生成DLL(含源码+注释)

文章目录 一、示例图二、普通项目需要改造的内容三、源码&#xff08;创建了一个TestDLL的项目&#xff0c;更改内容主要在pro文件和maindow.h文件&#xff09;TestDLL.promainwindow.hmainwindow.cppmainwindow.ui 总结 一、示例图 使用不同的编译模式编译&#xff0c;会在对…

卷积神经网络的感受野

经典目标检测和最新目标跟踪都用到了RPN(region proposal network)&#xff0c;锚框(anchor)是RPN的基础&#xff0c;感受野(receptive field, RF)是anchor的基础。本文介绍感受野及其计算方法&#xff0c;和有效感受野概念。 1.感受野概念 在典型CNN结构中&#xff0c;FC层(…

一款集成了主流大语言模型以及绘图模型的 APP, 采用 Flutter 开发,代码完全开源!!

一款集成了主流大语言模型以及绘图模型的 APP&#xff0c; 采用 Flutter 开发&#xff0c;代码完全开源&#xff0c;支持以下功能&#xff1a; 支持 OpenAI 的 GPT-3.5&#xff0c;GPT-4 大语言模型支持 Anthropic 的 Claude instant&#xff0c;Claude 2.0 大语言模型支持国产…

Python 框架学习 Django篇 (六) 数据表关联、ORM关联

在后端服务器开发中&#xff0c;特别是前后端分离的架构中数据库是非常重要的&#xff0c;后端主要就是负责管理数据&#xff0c;而我们经常使用的mysql、oracle 都是关系型数据库&#xff0c;什么是关系型数据库&#xff1f;就是建立在关系模型基础上的数据库&#xff0c;而最…

竞赛 深度学习人体跌倒检测 -yolo 机器视觉 opencv python

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习的人体跌倒检测算法研究与实现 ** 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f947;学长这里给一个题目综合评分(每项满…

flutter 使用FlutterJsonBeanFactory工具遇到的问题

如下图&#xff0c;使用FlutterJsonBeanFactory工具生成的数据类 但是其中 生成的 import package:null/&#xff0c;导致的错误&#xff1a;Target of URI doesn’t exist: ‘package:null/generated/json/asd.g.dart’ 尝试过的方法&#xff1a; 手动添加包名&#xff0c;…

面试算法39:直方图最大矩形面积

题目 直方图是由排列在同一基线上的相邻柱子组成的图形。输入一个由非负数组成的数组&#xff0c;数组中的数字是直方图中柱子的高。求直方图中最大矩形面积。假设直方图中柱子的宽都为1。例如&#xff0c;输入数组[3&#xff0c;2&#xff0c;5&#xff0c;4&#xff0c;6&am…

前后端交互系统:在Node.js中运行JavaScript

在Node.js中运行JavaScript&#xff0c;您需要编写适用于服务器端的代码&#xff0c;而不是浏览器端的代码。以下是一些示例代码&#xff0c;用于在Node.js中创建一个简单的HTTP服务器并在浏览器中访问它&#xff1a; // 引入Node.js内置的http模块 const http require(http);…

华为ERP,包含哪些内容?技术的先进性体现在哪里?

华为作为全球领先的信息和通信技术&#xff08;ICT&#xff09;解决方案提供商&#xff0c;其企业资源规划&#xff08;ERP&#xff09;系统是一个高度复杂且集成的管理软件平台&#xff0c;用于优化公司内部的业务流程和资源分配。华为ERP系统包括一系列模块和功能&#xff0c…

pytest-yaml 测试平台-2.支持上传YAML格式用例

前言 pytest-yaml 测试平台用例结构是遵循pytest-yaml-yoyo 框架用例规则。 如果你之前已经有用 pytest-yaml-yoyo 框架完成了yaml 用例的编写&#xff0c;可以直接在平台上导入yaml 用例。 yaml 用例 test_用例文件a.yml config:name: 单个用例文件test_a:name: extract提…

Linux多线程服务端编程:使用muduo C++网络库 学习笔记 第三章 多线程服务器的适用场合与常用编程模型

本文中的多线程服务器指运行在Linux上的独占式网络应用程序。硬件平台为Intel x86-64系列的多核CPU&#xff0c;单路或双路SMP&#xff08;Symmetric Multi-Processing&#xff0c;对称多处理&#xff0c;它是一种多核处理器架构&#xff0c;其中多个CPU核心共享系统的内存和其…