【C/C++】多态的概念 | 虚函数 | 虚函数指针

news2024/9/25 9:28:39

创作不易,本篇文章如果帮助到了你,还请点赞 关注支持一下♡>𖥦<)!!
主页专栏有更多知识,如有疑问欢迎大家指正讨论,共同进步!
🔥c++系列专栏:C/C++零基础到精通 🔥

给大家跳段街舞感谢支持!ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ

在这里插入图片描述

c语言内容💖:

专栏:c语言之路重点知识整合

【c语言】全部知识点总结


目录

  • 一、多态的概念
  • 二、虚函数
    • 1.虚函数大小
    • 2.虚函数指针
    • 3.虚函数列表

一、多态的概念

多态是C++面向对象编程中重要的特性。相同的行为方式可能导致不同的行为结果,即产生了多种形态行为,即多态

就是不同的类可以共享一个函数,但是各自的实现不同

为了实现多态,首先要有继承关系,在基类中声明一个虚函数,然后再派生类中进行不同的实现

根据继承中的父类指针可以指向子类对象:继承的条件下,父类的指针可以指向任何继承于该类的子类对象,多种子类对象具有多种形态由父类的指针统一管理 父类的指针也会具有多种形态

多种子类表现为多种形态由父类的指针进行统一,那么这个父类指针就具有了多种形态。(多态)


总结一下C++多态的必要条件:

  • 存在继承关系,并且父类类型的指针指向某个子类,通过该指针调用虚函数
  • 父类中存在虚函数 (virtual修饰) ,且子类中重写了父类的虚函数

重写:虚函数存在的前提下,子类中定义了和父类中一模一样的虚函数

举个栗子:

在这里插入图片描述

定义两个子类CSonCSon2继承于父类CFather,父类中定义两个虚函数

只在CSon子类中进行重写,在CSon2中不重写

#include <iostream>
using namespace std;
class CFather {
public:
	virtual void funSon()
	{
		cout << "CFather::virtual void fun()" << endl;
	}
	virtual void funSon2()
	{
		cout << "CFather::virtual void fun()" << endl;
	}
};


class CSon :public CFather
{
public:
	void fun1()
	{
		cout << "CSon::fun1()" << endl;
	}
	void funSon()
	{
		cout << "CSon::virtual void fun()" << endl;
	}
};
class CSon2 :public CFather
{
public:
	void funSon2()
	{
		cout << "CSon2::virtual void fun()" << endl;
	}
};
int main()
{
	CFather* pfa = new CSon;
	pfa->funSon();	//非多态
	pfa->funSon2(); //多态
	
	return 0;
}

其中:重写过父类中虚函数的CSon类中的funSon()实现多态,而未重写的funSon2()未实现多态

在这里插入图片描述

在这里插入图片描述

什么是虚函数?虚函数是如何实现多态的?

二、虚函数

1.虚函数大小

定义虚函数需要使用virtual关键字,虚函数的定义格式: virtual 返回类型 函数名();

virtual void fun();

当只定义一个空类时,输出类对象的大小为1 :为占位作用

在这里插入图片描述

如果在类中定义虚函数后,对象的内存空间会变为多少呢?

在这里插入图片描述

定义后执行发现,不管定义几个虚函数,对象的内存空间大小都为4

虚函数属于类,在编译器存在


2.虚函数指针

当我们在基类中定义了一个虚函数后并定义对象后(不定义对象没有虚函数指针),在调试下可以发现编译期自动添加了一个类型为void**的二级指针_vfptr

在这里插入图片描述
再定义一个对象,虚函数指针也随之增加了一个

在这里插入图片描述

但是查看地址,这两个虚函数指针指向了同一个内存空间,

虚函数指针属于对象,占用对象内存空间,定义多个对象就会存在多份的虚函数指针

  • 定义对象才会存在虚函数指针

  • 每个对象的虚函数指针都指向了同一个虚函数列表

  • 虚函数指针在构造函数中的初始化参数列表进行初始化(编译期自动完成)

在这里插入图片描述

3.虚函数列表

虚函数指针指向的是一个函数指针数组,为虚函数列表(vftable)
其中

每一个元素存储的是虚函数的地址,顺序为虚函数在类中定义顺序

在这里插入图片描述

  • 虚函数列表属于类,在编译期存在,为所有对象共享
  • 必须通过真实存在的对象调用,无对象或空指针对象无法调用虚函数

在这里插入图片描述

大家的点赞、收藏、关注将是我更新的最大动力! 欢迎留言或私信建议或问题。
大家的支持和反馈对我来说意义重大,我会继续不断努力提供有价值的内容!如果本文哪里有错误的地方还请大家多多指出(●'◡'●)

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

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

相关文章

Linux操作系统--vi/vim编辑器

1.Vi/Vim简介 Vi 是 Unix 操作系统和类 Unix 操作系统中最通用的文本编辑器。 VIM 编辑器是从 VI 发展出来的一个性能更强大的文本编辑器。可以主动的以字体颜色辨别语法的正确性,方便程序设计。VIM 与 VI 编辑器完全兼容。这里简单的理解为如果你需要使用指令取操作Linux系…

【LeetCode-中等题】142. 环形链表 II

文章目录 题目方法一&#xff1a;哈希表set去重方法二&#xff1a;快慢指针 题目 方法一&#xff1a;哈希表set去重 思路&#xff1a;我们遍历链表中的每个节点&#xff0c;并将它记录下来&#xff1b;一旦遇到了此前遍历过的节点&#xff0c;就可以判定链表中存在环。借助哈希…

nonlocal关键字声明

nonlocal关键字声明 作用 使得内层函数可以使用/修改外层函数的变量 值得注意的是&#xff0c;在未使用nonlocal声明时 对于外层函数中的可变对象&#xff0c;内层函数即可访问&#xff0c;也可以修改 def outer():x, y [1], [2]def inner(z):x.append(1)print(x)print(z)r…

英特尔oneAPI人工智能黑客松 - 坚果识别实战

写在前面&#xff1a;博主是一只经过实战开发历练后投身培训事业的“小山猪”&#xff0c;昵称取自动画片《狮子王》中的“彭彭”&#xff0c;总是以乐观、积极的心态对待周边的事物。本人的技术路线从Java全栈工程师一路奔向大数据开发、数据挖掘领域&#xff0c;如今终有小成…

Ubuntu断电重启后黑屏左上角光标闪烁,分辨率低解决办法,ubuntu系统display只有4:3 怎么办?太卡

这个问题主要是显卡驱动问题&#xff0c;按照步骤更新显卡驱动 1&#xff0c;选择metapackage 并且选择proprietary版本&#xff0c;选择版本号选择最新的版本。 2&#xff0c;具体步骤参考 前言 笔者在安装显卡驱动时并未遇到问题&#xff0c;主要是后续屏幕亮度无法调节&…

qt在线包下载安装出错 无法检索远程树

我的问题好像是在安装Qt5.15.2出现的。 我的情况是由于网络问题问题&#xff0c;设置开启了本机的代理之后&#xff0c;就可以正常下载了。

STM32F103 USB OTA升级APP (二)

接上一篇STM32F103 USB OTA升级BootLoader (一)&#xff1a;跳转链接 修改程序启动地址和Flash大小 修改main.c代码 #include "main.h" #include "usart.h" #include "usb_device.h" #include "gpio.h" #include "Update.h&quo…

空时自适应处理用于机载雷达——空时处理基础知识(Matla代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

基于STM32CUBEMX驱动TMOS模块STHS34PF80(6)----获取状态数据

基于STM32CUBEMX驱动TMOS模块STHS34PF80----6.获取状态数据 概述视频教学样品申请参考Demo参考程序获取数据获取数据标志位使用数据准备就绪信号嵌入式智能数字算法的输出数据主程序 概述 STHS34PF80传感器项目种修改 Arduino 脚本&#xff0c;重新移植到STM32的MCU中。 该项目…

PAT 1127 ZigZagging on a Tree

个人学习记录&#xff0c;代码难免不尽人意。 Suppose that all the keys in a binary tree are distinct positive integers. A unique binary tree can be determined by a given pair of postorder and inorder traversal sequences. And it is a simple standard routine t…

Experience Design(XD)软件安装包分享(附安装教程)

目录 一、软件简介 二、软件下载 一、软件简介 Experience Design&#xff08;XD&#xff09;是Adobe公司开发的一款用户体验设计工具&#xff0c;广泛应用于网页设计、移动应用设计、交互设计等领域。以下是XD软件的主要特点和功能&#xff1a; 界面设计&#xff1a;XD提供…

android2022配置opencv4android480

1&#xff0c;安装android studio2022。 2&#xff0c;下载OPENCV4ANDROID&#xff0c;解压到任意盘中。 3&#xff0c;File->New->New Project&#xff0c;选择Empty Views Activity。再选择语言&#xff0c;本文选择JAVA。 4&#xff0c;File->New->Import Modu…

白嫖idea

白嫖idea 地址 https://www.jetbrains.com/toolbox-app/

Spark中join和cogroup

笔者最近在复习spark&#xff0c;发现对cogroup算子掌握不牢固。因此写下这篇博客&#xff0c;方便以后学习。 join算子 join算子相当于将两个rdd进行内连接&#xff0c;在join的结果中&#xff0c;返回值是key和元组 cogroup算子 cogroup算子相当于将两个rdd中 相同键的每…

LeetCode538. 把二叉搜索树转换为累加树

538. 把二叉搜索树转换为累加树 文章目录 [538. 把二叉搜索树转换为累加树](https://leetcode.cn/problems/convert-bst-to-greater-tree/)一、题目二、题解方法一&#xff1a;递归&#xff08;中序遍历与节点更新&#xff09;方法二&#xff1a;反向中序遍历与累加更新&#x…

作业人员护目镜佩戴自动识别

作业人员护目镜佩戴自动识别通过pythonyolo深度学习算法模型&#xff0c;作业人员护目镜佩戴自动识别利用布设摄像头并结合图像算法能够实时监测作业人员是否佩戴护目镜。一旦发现未佩戴的情况立即发出警告&#xff0c;并及时记录异常情况。在YOLOv1提出之前&#xff0c;R-CNN系…

iPhone手机如何删除照片应用程序的文稿与数据

场景&#xff1a;iPhone使用多年&#xff08;穷没钱换新的&#xff09;照片视频一直没有删除&#xff0c;最近打开微信提示空间不足&#xff0c;删除100多G照片后&#xff0c;照片应用程序的文稿与数据仍然100G没有变化。 不想重置手机&#xff0c;处理方法如下&#xff0c;PC端…

.netcore发布独立版部署

.NetCore 在发布独立版时会打包独立环境&#xff0c;就算服务没有安装环境也能运行&#xff0c;这就是.NetCore跨平台的特性之一。 按照微软的传统配套&#xff0c;c#开发的项目一般都是发布打包程序部署在iis&#xff0c;但是.netcore 跨平台的&#xff0c;就是说当发布独立版…

全栈之前端 | 2.CSS3基础知识之选择器学习

关注回复【学习交流群】加入【安全开发运维】答疑交流群 请朋友们【多多点击文中的广告】&#xff0c;支持作者更新更多文章。 目录: 0x00 前言简述 Q: 选择器是什么&#xff1f; 你也许已经见过选择器了。CSS 选择器是 CSS 规则的第一部分。它是元素和其他部分组合起来告诉浏览…

Sping源码(七)— 后置处理器(自定义后置处理器)

上一篇中简单介绍了Spring中invokeBeanFactoryPostProcessors方法的执行流程&#xff0c;以及BFPP和BDRPP类的介绍&#xff0c;这篇文章我们来自定义实现一个类的后置处理器。 自定义PostProcessor 自定义PostProcessor的方式一共两种&#xff0c;都是根据invokeBeanFactoryPo…