当前位置: 首页 > news >正文

【C++学习手札】一文带你认识C++虚函数(内层剖析)

                                        食用指南:本文在有C基础的情况下食用更佳  

                                       🍀本文前置知识: C++初识继承

                                       ♈️今日夜电波:No title —REOL

                                                                1:02 ━━━━━━️💟──────── 4:03
                                                                    🔄   ◀️   ⏸   ▶️    ☰ 

                                      💗关注👍点赞🙌收藏您的每一次鼓励都是对我莫大的支持😍 


目录

✅虚函数的概念

⭕虚函数的结构

定义

内层结构(重要)

☑如何查看类的内层结构

✔虚函数的应用案例


 ✅虚函数的概念

        C++面向对象中的多态性是指同一种类型的对象在不同的情况下表现出不同的行为。这种多态性可以通过虚函数来实现。在C++中,虚函数是指在基类中声明的函数,在派生类中可以被重写,从而实现不同的行为。当使用基类指针或引用调用虚函数时,实际调用的是派生类中重写的函数,而不是基类中的函数。 通过使用虚函数,可以实现运行时多态性,即在程序运行时才确定调用哪个函数,而不是在编译时确定。这种多态性可以提高程序的灵活性和可扩展性,使得程序更加易于维护和扩展。

      简而言之,就是用父类型别的指针指向其子类,然后通过父类的指针调用实际子类的成员函数。

        🌰

class Animal{public:void sleep(void){cout << "animal 动物在睡觉" << endl;}};class Cat :public Animal{public:void sleep(void){cout << "Cat 猫在睡觉!! 喵喵" << endl;}};void test01(){//用基类(指针或引用) 保存 子类对象(向上转换)Animal * p = new Cat;p-> sleep();//调用的是基类的sleepCat cat;  Animal & ob = cat;ob.sleep();//调用的是基类的sleep}

        在这个例子中,我们想实现的功能是什么呢?我们用的是父类的指针指向了子类的空间,想要调用其中的成员函数,但是事实真的如我们所愿吗?请看以下运行结果:

         可以看到我们实际上调用的都是父类中的成员函数,而这也是C++继承在作祟。对此,我们使用虚函数!(仅仅只是加了一个 virtual)

class Animal{public:virtual void sleep(void){cout << "animal 动物在睡觉" << endl;}};

运行结果又是如何呢?如下:

         这是什么原因呢?这就要提到虚函数的结构了!

虚函数的结构

        定义

virtual 函数(包涵返回值、参数等等(就是在前面多加了个virtual))

        内层结构(重要)

        我们使用Develop Command Prompt for VS 2022 打开相应的类结构,如下为加了virtual的父类Animal

        vfptr是虚函数指针 指向的是虚函数表(vftable)
        vftable表存放的是 vfptr做保存的函数入口地址

         一图让你明白~

         当函数前加了virtual后会自动生成一个vfptr指针以及一个vftable,虚函数指针会指向这个虚函数表,而函数表中通常储存着虚函数入口的地址。而这些地址的存储也是有一定的规则的,他们通过序号以及当前的虚指针相对于虚基类的首地址的偏移量。当其中有多个虚函数时,以便找到相应的函数。

         重要的来了,那为啥当我们在父类指针中定义了虚函数,而在子类中就能实现用父类指针就可以访问子类的成员函数了呢?

        这是因为:当虚函数涉及到继承的时候 子类 会继承 父类的(虚函数指针vfptr 虚函数表vftable),编译器会将虚函数表中的函数入口地址 更新 成子类的 同名(返回值、参数都同)的函数入口地址。如果基类指针、引用 访问虚函数的时候 就会 间接的调用 子类的虚函数。

        二图让你明白~

        

 看到这里,相信你的好奇心起来了,如何查找类的结构呢?别急~接下来就分享给你(*╹▽╹*)


如何查看类的内层结构

        1、首先在你的任务栏中搜索        Develop Command Prompt for VS 2022   (2022是版本,你可以根据自己的版本变更)

         2、打开后回到你的VS执行以下操作

         3、回到 Develop Command Prompt for VS 2022,输入以下命令

        如果你的文件是在E盘 你首先得先进入E盘 所以输入 E: 如果是C盘则C:以此类推

在进入所在盘后,进入到对应的路径 cd + 路径 如下:

         4、输入对应的操作  

        cl /d1 reportSingleClassLayout+类名 类所在程序名.cpp

         如下:


虚函数的应用案例

        (基类指针、引用 作为函数的参数)

         🌰

#include <iostream>using namespace std;class Base {public:virtual void sleep(void){cout << "父亲在睡觉" << endl;}};class Son1 :public Base{public:void sleep(void){cout << "Son1在安静的睡觉" << endl;}};class Son2 :public Base{public:virtual void sleep(void){cout << "Son2在轻度的睡觉" << endl;}};class Son3 :public Base{public:virtual void sleep(void){cout << "Son3在雨声般的睡觉" << endl;}};class Son4 :public Base{public:virtual void sleep(void){cout << "Son4在鼾声如雷" << endl;}}; //以基类指针作为函数的参数 函数可以操作该基类派生出的任意子类对象void sleepFun(Base & ob){ob.sleep();}int main(int argc, char* argv[]){Son1 ob1;Son2 ob2;Son3 ob3;Son4 ob4;sleepFun(ob1);sleepFun(ob2);sleepFun(ob3);sleepFun(ob4);return 0;}

        运行结果如下:


                感谢你耐心的看到这里ღ( ´・ᴗ・` )比心,如有哪里有错误请踢一脚作者o(╥﹏╥)o!  

                                 

                                                                 给个三连再走嘛~      

相关文章:

【C++学习手札】一文带你认识C++虚函数(内层剖析)

食用指南&#xff1a;本文在有C基础的情况下食用更佳 &#x1f340;本文前置知识&#xff1a; C初识继承 ♈️今日夜电波&#xff1a;No title —REOL 1:02 ━━━━━━️&#x1f49f;──────── 4:03 …...

Python“牵手”1688商品评论数据采集方法,1688API申请指南

1688平台API接口是为开发电商类应用程序而设计的一套完整的、跨浏览器、跨平台的接口规范&#xff0c;1688API接口是指通过编程的方式&#xff0c;让开发者能够通过HTTP协议直接访问1688平台的数据&#xff0c;包括商品信息、店铺信息、物流信息等&#xff0c;从而实现1688平台…...

“深入解析JVM内部机制:探秘Java虚拟机的奥秘“

标题&#xff1a;深入解析JVM内部机制&#xff1a;探秘Java虚拟机的奥秘 摘要&#xff1a;本文将深入解析JVM&#xff08;Java虚拟机&#xff09;的内部机制&#xff0c;从字节码执行到垃圾回收&#xff0c;逐步揭示Java程序运行的奥秘。通过理论分析和示例代码&#xff0c;读…...

【系统工具】开源服务器监控工具WGCLOUD初体验

经常看到服务器上传下载流量一直在跑&#xff0c;也不知道是啥软件在偷偷联网~~~官网地址&#xff1a;www.wgstart.com&#xff0c;个人使用是免费的。 WGCLOUD官网介绍 "WGCLOUD支持主机各种指标监测&#xff08;cpu使用率&#xff0c;cpu温度&#xff0c;内存使用率&am…...

powerBI应用技巧

power BI应用技巧 持续跟新 1.函数日期表 使用高级编辑器—M函数&#xff08;把下面代码直接复制即可&#xff09; 版本1&#xff1a;前单位写的M函数&#xff0c;日期是2021年开始的 letdate(optional 请输入开始年份 as number,optional 请输入结束年份 as number)>l…...

RK3568背光调试分享

一.PWM 驱动 驱动文件所在位置: drivers/pwm/pwm-rockchip.c 3.10 和 4.4 及以上版本内核下驱动文件名字是同一个, pwm-rockchip.c 只支持 Continuous mode , 但是里面的代码有些差别。 4.4 及以上内核版本将 pwm_config() , pwm_enable()...

Numpy入门(2)—随机数

随机数np.random 主要知识点&#xff1a; 创建ndarray随机数组随机打乱ndarray元素顺序随机选取元素 2.1 创建随机ndarray数组 创建随机ndarray数组主要包含设置随机种子、均匀分布和正态分布三部分内容&#xff0c;具体代码如下所示。 设置随机数种子 # 可以多次运行&am…...

ansible的playbook剧本

playbook剧本 PlayBook1.playbooks 本身由以下各部分组成2.示例&#xff1a;3.运行playbook补充参数&#xff1a; 4.定义、引用变量5.指定远程主机sudo切换用户6.when条件判断7.迭代8.Templates 模块1.先准备一个以 .j2 为后缀的 template 模板文件&#xff0c;设置引用的变量2…...

【03 英语语法:从句(名词从句、定语从句/形容词从句、状语从句/副词从句)】

从句 从句&#xff1a;名词从句、定语从句、状语从句&#xff08;名定状名形副&#xff09;1. 名词从句&#xff08;名词&#xff09;&#xff1a;主语、宾语、表语、同位语、宾补▲名词从句的种类&#xff08;按引导词&#xff09;&#xff1a; that、whether、疑问词 句子⑴…...

vue动态修改audio地址

问题&#xff1a;点击后替换url地址&#xff0c;实现了&#xff0c;但是播放器依旧没有反应。 解决&#xff1a;vue中动态替换只是替换了地址&#xff0c;并没有告诉audio标签是否要执行&#xff0c;执行什么操作。要load后才能让它知道&#xff0c;是在喊他&#xff0c;他需求…...

CF113A Grammar Lessons 题解

一道模拟题。 题目传送门 题目意思&#xff1a; 给你一个句子&#xff0c;让你检查这个句子的语法是否正确。&#xff08;语法请自行在题目中查看&#xff09; 思路&#xff1a; 就是模拟。依次判断这个句子是否符合每一条语法即可。但是细节很多就因为细节我错了好多次&…...

puzzle(0414)六边形拼图

目录 六边形拼图 简单 中等 困难 六边形拼图 taptap小游戏 简单 &#xff08;3&#xff09; &#xff08;4&#xff09; 中等 &#xff08;3&#xff09; &#xff08;4&#xff09; 困难 &#xff08;2&#xff09; &#xff08;3&#xff09; &#xff08;4&#xff…...

回归预测 | MATLAB实现基于SAE堆叠自编辑器多输入单输出回归预测

回归预测 | MATLAB实现基于SAE堆叠自编辑器多输入单输出回归预测 目录 回归预测 | MATLAB实现基于SAE堆叠自编辑器多输入单输出回归预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.MATLAB实现基于SAE堆叠自编辑器多输入单输出回归预测&#xff1b; 2.运行环…...

BEV感知实时构建路口拓扑 觉非科技基于MapTR的优化与实践

近期&#xff0c;觉非科技通过在车端与路端的大规模数据积累&#xff0c;基于MapTR&#xff08;Map TRansformer&#xff09;方法提出了创新与优化&#xff1a;①对车道信息的表达方式进行优化&#xff0c;并简化了模型结构&#xff1b;②在MapTR的基础上加入了地图先验信息&am…...

如何在TikTok“点火”?用时下最流行的工具解码赚钱

抖音电商飞速发展到今天&#xff0c;训练出一帮极具紧张感、高效性&#xff0c;和“数据特征”凸显的电商从业者。 注意&#xff0c;这里的"数据特征"不单单是数据分析、数据导向那么简单&#xff0c;而是被竟对、平台、市场的现实教育出来的“数据工具意识”。 “…...

set NOCOUNT on

SET NOCOUNT ON 是一条 SQL 语句&#xff0c;用于禁止在执行查询时返回受影响的行数消息。通常&#xff0c;当执行 INSERT、UPDATE、DELETE 等操作时&#xff0c;数据库会返回一个消息&#xff0c;表示受影响的行数。但在某些情况下&#xff0c;你可能希望禁用这些消息&#xf…...

垃圾回收机制

什么是内存泄漏&#xff1f; 内存泄漏是指程序中已经不再使用的内存却没有被正确释放或回收的情况。在编程中&#xff0c;当对象或数据不再被程序使用&#xff0c;但其所占用的内存空间没有被垃圾回收机制回收&#xff0c;就会导致内存泄漏。 内存泄漏可能会导致程序的内存消…...

Golang 程序性能优化利器 PGO 详解(一):简单介绍及使用

在软件开发过程中&#xff0c;性能优化是不可或缺的一部分。无论是在Web服务、数据处理系统还是实时通信中&#xff0c;良好的性能都是至关重要的。Golang 从1.20版版本开始引入的 Profile Guided Optimization&#xff08;PGO&#xff09;机制能够帮助更好地优化 Go 程序的性能…...

redis key操作的相关命令

目录 1、del key 2、dump key 3、exists key 4、expire key seconds 5、expireat key timestamp 6、pexpire key milliseconds 7、pexpireat key milliseconds-timestamp 8、keys pattern 9、move key db …...

WebRTC | 网络传输协议RTP与RTCP

目录 一、UDP与TCP 1. TCP 2. UDP 二、RTP 1. RTP协议头 &#xff08;1&#xff09;V&#xff08;Version&#xff09;字段 &#xff08;2&#xff09;P&#xff08;Padding&#xff09;字段 &#xff08;3&#xff09;X&#xff08;eXtension&#xff09;字段 &#x…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)

🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

Java 二维码

Java 二维码 **技术&#xff1a;**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...

用机器学习破解新能源领域的“弃风”难题

音乐发烧友深有体会&#xff0c;玩音乐的本质就是玩电网。火电声音偏暖&#xff0c;水电偏冷&#xff0c;风电偏空旷。至于太阳能发的电&#xff0c;则略显朦胧和单薄。 不知你是否有感觉&#xff0c;近两年家里的音响声音越来越冷&#xff0c;听起来越来越单薄&#xff1f; —…...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

elementUI点击浏览table所选行数据查看文档

项目场景&#xff1a; table按照要求特定的数据变成按钮可以点击 解决方案&#xff1a; <el-table-columnprop"mlname"label"名称"align"center"width"180"><template slot-scope"scope"><el-buttonv-if&qu…...

Python学习(8) ----- Python的类与对象

Python 中的类&#xff08;Class&#xff09;与对象&#xff08;Object&#xff09;是面向对象编程&#xff08;OOP&#xff09;的核心。我们可以通过“类是模板&#xff0c;对象是实例”来理解它们的关系。 &#x1f9f1; 一句话理解&#xff1a; 类就像“图纸”&#xff0c;对…...

路由基础-路由表

本篇将会向读者介绍路由的基本概念。 前言 在一个典型的数据通信网络中&#xff0c;往往存在多个不同的IP网段&#xff0c;数据在不同的IP网段之间交互是需要借助三层设备的&#xff0c;这些设备具备路由能力&#xff0c;能够实现数据的跨网段转发。 路由是数据通信网络中最基…...

CSS 工具对比:UnoCSS vs Tailwind CSS,谁是你的菜?

在现代前端开发中&#xff0c;Utility-First (功能优先) CSS 框架已经成为主流。其中&#xff0c;Tailwind CSS 无疑是市场的领导者和标杆。然而&#xff0c;一个名为 UnoCSS 的新星正以其惊人的性能和极致的灵活性迅速崛起。 这篇文章将深入探讨这两款工具的核心理念、技术差…...

鸿蒙Navigation路由导航-基本使用介绍

1. Navigation介绍 Navigation组件是路由导航的根视图容器&#xff0c;一般作为Page页面的根容器使用&#xff0c;其内部默认包含了标题栏、内容区和工具栏&#xff0c;其中内容区默认首页显示导航内容&#xff08;Navigation的子组件&#xff09;或非首页显示&#xff08;Nav…...