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

【C++】函数重载+引用

大家好,我是苏貝,本篇博客带大家了解C++的函数重载和引用,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️
在这里插入图片描述


目录

  • 一. 预处理、编译、汇编、链接
  • 二. 函数重载
    • 1 概念
    • 2 C++支持函数重载的原理—名字修饰
  • 三. 引用
    • 1 概念
    • 2 引用特性
    • 3 常引用(权限的缩小/放大)
    • 4 使用场景
    • 5 引用和指针的区别

一. 预处理、编译、汇编、链接

在C/C++中,一个程序要运行起来,需要经历以下4个阶段:预处理、编译、汇编、链接

  1. 预处理:头文件展开,宏替换,条件编译,去掉注释
  2. 编译:检查语法,形成汇编代码。如果函数的声明和定义分离,那么main函数所在文件中有函数声明就可以编译成功
  3. 汇编:把汇编代码转成二进制机器码
  4. 链接:将同一项目文件经过汇编后形成的文件合并到一起,符号表的合并和符号表的重定位。
    如果函数的声明和定义分离,那么此时编译器就会通过函数名到符号表(符号表可用于确定变量或函数在内存中的位置)里查找函数的地址(地址通过函数的定义确定),所以如果没有函数定义,编译器会报错

下面用Linux的文件经过上述4个步骤后形成的文件举例
在这里插入图片描述

因为预处理阶段会展开头文件,因此以.cpp为后缀的文件中就将头文件的内容拷贝了,所以预处理结束后,Stack.h文件不会再形成.i文件

二. 函数重载

1 概念

函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同,常用来处理实现功能类似数据类型不同的问题。

参数个数不同
在这里插入图片描述

参数的类型不同

在这里插入图片描述

参数的顺序不同

在这里插入图片描述

2 C++支持函数重载的原理—名字修饰

为什么C语言不支持函数重载,而C++支持呢?因为名字修饰

在C/C++中,一个程序要运行起来,需要经历预处理、编译、汇编和链接。链接时,面对调用的函数(如Add函数),链接器会使用哪个名字去找呢?这里每个编译器都有自己的 函数名修饰规则。由于Linux的函数名修饰规则简单,vs的较为复杂,因此我们下面用Linux来演示

用gcc编译器
写出test.c的代码
在这里插入图片描述

用gcc编译写出可执行程序,再使用objdump -S a.out来查看函数名修饰

在这里插入图片描述

我们发现,C语言的函数名修饰规则就是用自己的函数名,所以不能存在同名函数,否则编译器区分不开
在这里插入图片描述

采用g++编译器
将上面的test.c的内容拷贝到test1.cpp中,用g++编译形成可执行程序a.out,再执行命令objdump -S a.out查看函数名修饰
在这里插入图片描述

我们发现,C++的函数名修饰规则就不是用自己的函数名了。在Linux中,函数名修饰以_Z为前缀,后接函数名的字符个数,再接函数名,最后是函数形参的类型缩写(按顺序)。所以如果还有函数void f(int a),那么经过修饰,结果为_Z1fi
在这里插入图片描述

通过这里就理解了C语言没办法支持重载,因为同名函数没办法区分。而C++是通过函数修饰规则来区分,只要参数不同,修饰出来的名字就不一样,就支持了重载。另外如果两个函数函数名和参数是一样的,返回值不同是不构成重载的,因为调用时编译器没办法区分。

三. 引用

1 概念

引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间
比如:李逵,在家称为"铁牛",江湖上人称"黑旋风"。铁牛和黑旋风就是李逵的别名

类型& 引用变量名(对象名) = 引用实体;
注意:引用类型必须和引用实体是同种类型的
在这里插入图片描述
在这里插入图片描述

第一个&表示引用,之后的两个&是对变量取地址。由结果知,引用变量b和它引用的变量a公用一块内存空间

根据上面的了解,看看下面代码的结果是什么?

在这里插入图片描述

答案是12,因为引用变量b和它引用的变量a公用一块内存空间

2 引用特性

  1. 引用在定义时必须初始化

在这里插入图片描述

  1. 引用定义后,不能改变指向

在这里插入图片描述
在这里插入图片描述

  1. 一个变量可以有多个引用

在这里插入图片描述

3 常引用(权限的缩小/放大)

权限可以缩小,但不能放大

在这里插入图片描述

1.它是我们常见的引用;
2.引用c被const修饰,表示不能通过修改c而修改a,由a的可读可写变为c的只读,这是权限的缩小。
3.10是只读的,但d是可读可写的,权限不能放大,报错
4.10是只读的,e也是只读的,权限不变,不会报错
5.x是只读的,但y是可读可写的,权限不能放大,报错

在这里插入图片描述

1err,2ok
表达式的返回值以临时变量的形式存储,临时变量具有常性,不能修改,即只读,因此引用的话要加const。

在这里插入图片描述

权限不能放大,func参数的形参:a+b的返回值和10都是只读的,实参:int& a是可读可写的,权限放大了,报错

在这里插入图片描述

发生类型转换时,中间会产生临时变量。
在这里插入图片描述

  1. 由double变为int,会发生强制类型转换,产生临时变量。相当于(int)d后, 得到了一个没有名字的变量,它的类型为int,值为1,我们把这个临时变量(1)拷贝给变量a,在执行完该语句后临时变量会被释放
  2. 由double变为类型为int的引用,会发生类型转换,产生临时变量,临时变量具有常性,因此要在引用前加const

4 使用场景

  1. 做参数
    我们对swap函数已经很熟悉了,之前函数的形参都是指针,现在我们用引用来当形参
    在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

注意:引用做形参时,引用变量名可以和实参名一样,但不建议

  1. 做返回值
    查看下面代码,它的结果是什么?
    在这里插入图片描述

结果是10,毫无疑问。那么,函数func1返回的是a吗?不是,a出了func1的函数作用域就被销毁,所以返回的是a的拷贝。

那下面代码的结果呢?
在这里插入图片描述

随机值。因为func1函数运行结束后,该函数对应的栈空间就被回收了,所以变量a的空间被回收,然而函数的返回值是变量a的别名,它是野引用,因此用ret接受函数返回值时也就是访问了已被回收的a的空间,故结果是随机值

如果我们仔细一点的话,我们还能看到编译器会报警告。至于为什么警告是说返回的是地址而非引用,我们下面会讲到

在这里插入图片描述

通过上面的了解,我们知道,如果函数的返回值出了该函数的作用域就被销毁(如局部变量),那就不能用引用返回。因此,能用引用返回的,是全局变量/静态变量/堆上变量等

5 引用和指针的区别

从语法上:

  1. 引用是别名,不开空间,指针要开空间
  2. 引用必须初始化,指针可以不初始化。所以引用更安全,因为没有空引用,但有空指针。容易出现野指针,但不容易出现野引用
  3. 引用不能改变指向,指针可以
  4. 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32 位平台下占4个字节,64位平台下占8个字节)
  5. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
  6. 有多级指针,但没有多级引用
  7. 访问实体方式不同,指针需要显式解引用,引用编译器自己处理

从底层上:
在汇编层面上,没有引用,都是指针,引用编译后也转成指针了。因此,引用在底层上也要开空间,但我们一般都说引用不开空间(语法层面)


好了,那么本篇博客就到此结束了,如果你觉得本篇博客对你有些帮助,可以给个大大的赞👍吗,感谢看到这里,我们下篇博客见❤️

相关文章:

【C++】函数重载+引用

大家好,我是苏貝,本篇博客带大家了解C的函数重载和引用,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️ 目录 一. 预处理、编译、汇编、链接二. 函数重载1 概念2 C支持函数重载的原理—名字修饰…...

华为S5735交换机console密码重置和恢复出厂设置

比较简单,简单说就是进入bootload清除密码,然后进入default mode下重置密码。 1.开机按CtrlB,进入启动加载菜单(BootLoad menu) 拨电源重启交换机,大约开机10多秒的时候会出现提示按CtrlB可以进入BootLoa…...

Spring Security无脑使用

步骤1&#xff1a;添加Spring Security依赖 在你的Spring Boot项目的pom.xml文件中&#xff0c;添加Spring Security的依赖&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</art…...

学习 PostgreSQL + Spring Boot 3 +mybatisplus整合过程中的报错记录

今天计划学习 PostgreSQL&#xff0c;并顺便尝试使用 Spring Boot 3.x 框架&#xff0c;打算整合 Spring Boot 3、PostgreSQL 和 MyBatis-Plus。整合后一直出现以下报错&#xff1a; 去AI上面搜了讲的是sqlSessionFactory 或 sqlSessionTemplate 没有正确配置 初始分析&#…...

立仪光谱共焦传感器在玻璃测量技术上的突破

近年来&#xff0c;随着科技的不断发展&#xff0c;光谱共焦传感器逐渐成为了工业检测领域的重要工具。尤其是在玻璃这种透明材质的厚度测量中&#xff0c;光谱共焦传感器展现出了其独特的优势。立仪科技小编将围绕光谱共焦传感器在玻璃行业中的应用&#xff0c;从问题、分析到…...

Llama系列上新多模态!3.2版本开源超闭源,还和Arm联手搞了手机优化版,Meta首款多模态Llama 3.2开源!1B羊驼宝宝,跑在手机上了

Llama系列上新多模态&#xff01;3.2版本开源超闭源&#xff0c;还和Arm联手搞了手机优化版&#xff0c;Meta首款多模态Llama 3.2开源&#xff01;1B羊驼宝宝&#xff0c;跑在手机上了&#xff01; 在多模态领域&#xff0c;开源模型也超闭源了&#xff01; 就在刚刚结束的Met…...

系统缺失mfc140.dll的修复方法,有效修复错误mfc140.dll详细步骤

mfc140.dll丢失原因分析 1 系统文件损坏或病毒感染 系统文件损坏或被病毒感染是导致mfc140.dll丢失的常见原因之一。根据用户反馈和安全研究报告&#xff0c;大约有30%的mfc140.dll丢失案例与系统文件损坏或病毒感染有关。病毒、木马或其他恶意软件可能会破坏或删除系统中的m…...

移动app的UI和接口自动化测试怎么进行?

标题&#xff1a;从0到1&#xff1a;移动App的UI和接口自动化测试 导语&#xff1a;移动App的快速发展使得UI和接口自动化测试成为了确保应用质量的重要环节。本文将从零开始介绍移动App的UI和接口自动化测试的基本概念以及如何进行测试。 第一部分&#xff1a;了解移动App自动…...

Unity实现自定义图集(二)

以下内容是根据Unity 2020.1.0f1版本进行编写的   实现一个自定义图集,该怎么入手呢。首先简单思考一下unity是怎么实现图集的。 因为unity的ui部分是开源的,所以我们可以看到UGUI的源代码,另外,Unity的内置Shader也是开源的,可以直接在官网下载(在下载的网页选择Built…...

智能码二维码zhinengma.cn的动态数据更新是如何实现的?

智能码二维码的动态数据更新功能是通过其背后的技术原理实现的&#xff0c;主要依赖于服务器和二维码的链接结构。以下是具体介绍&#xff1a; 动态数据更新的实现原理 链接嵌入&#xff1a;动态二维码中嵌入了一个链接&#xff0c;该链接指向服务器上的数据源。数据请求与更…...

uniapp view怎么按长度排列一行最多四个元素,并且换行后,每一行之间都有间隔

推荐学习文档 golang应用级os框架&#xff0c;欢迎stargolang应用级os框架使用案例&#xff0c;欢迎star案例&#xff1a;基于golang开发的一款超有个性的旅游计划app经历golang实战大纲golang优秀开发常用开源库汇总想学习更多golang知识&#xff0c;这里有免费的golang学习笔…...

Android列表组件api

目录 1.ListView控件 1&#xff09;android:divider 2&#xff09;android:dividerHeight 3&#xff09;android:entries 4&#xff09;android:footerDividersEnabled 5&#xff09;android:headerDividersEnabled 6&#xff09;android:listSelector 7&#xff09;android:sc…...

ToB项目身份认证AD集成(完):利用ldap.js实现与windows AD对接实现用户搜索、认证、密码修改等功能 - 以及针对中文转义问题的补丁方法介绍

在前面的两篇文章中&#xff0c;我详细的介绍了使用ldap与window AD服务集成&#xff0c;实现ToB项目中的身份认证集成方案&#xff0c;包括技术方案介绍、环境配置&#xff1a; ToB项目身份认证AD集成&#xff08;一&#xff09;&#xff1a;基于目录的用户管理、LDAP和Active…...

SpringBoot+SeetaFace6搭建人脸识别平台

前言 最近多个项目需要接入人脸识别功能&#xff0c;之前的方案是使用百度云api集成&#xff0c;但是后续部分项目是内网部署及使用&#xff0c;考虑到接入复杂程度及收费等多种因素&#xff0c;决定参考开源方案自己搭建&#xff0c;保证服务的稳定性与可靠性 项目地址&…...

MySQL-06.DDL-表结构操作-创建

一.DDL(表操作) create database db01;use db01;create table tb_user(id int comment ID&#xff0c;唯一标识,username varchar(20) comment 用户名,name varchar(10) comment 姓名,age int comment 年龄,gender char(1) comment 性别 ) comment 用户表; 此时并没有限制ID为…...

在Visual Studio中使用CMakeLists.txt集成EasyX库的详细指南

EasyX库是一款专为Windows平台设计的轻量级C图形库&#xff0c;适合初学者和教育领域使用。结合Visual Studio和CMake工具链&#xff0c;用户可以轻松创建C项目&#xff0c;并集成EasyX库&#xff0c;实现丰富的图形编程效果。本文将详细介绍如何在Visual Studio中通过CMakeLis…...

CRC码计算原理

CRC8这里先以CRC8来说明CRC的计算过程1、CRC8在线计算器通过CRC在线计算器可以看见CRC8的特征多项式:x8+x2+x+1,初始值为0000’0000。CRC计算的核心是:反转+异或+移位(此处的CRC8没有涉及反转,见后面CRC16)。2、CRC8计算过程(1)、取值从高到低依次取需校验数据的位,这里…...

对高危漏洞“Docker Engine API is accessible without authentication”的修复

一.背景 之前文章maven项目容器化运行之1-基于1Panel软件将docker镜像构建能力分享给局域网_1panel 构建镜像-CSDN博客将1Panel软件的Doocker端口给到了局域网&#xff0c;安全组兄弟扫描认为是高危漏洞&#xff0c;可能导致攻击者获取对Docker主机的完全控制权。 二.修复的建…...

两种方式创建Vue项目

文章目录 引言利用Vue命令创建Vue项目准备工作安装Vue CLI创建Vue项目方法一&#xff1a;使用vue init命令方法二&#xff1a;使用vue create命令启动Vue项目 利用Vite工具创建Vue项目概述利用Vite创建项目启动项目 结语 引言 大家好&#xff0c;今天我将向大家展示如何使用不…...

深入理解 C/C++ 指针

深入理解 C 指针&#xff1a;指针、解引用与指针变量的详细解析 前言 在 C 编程语言中&#xff0c;指针 是一个非常强大且重要的概念。对于初学者来说&#xff0c;指针往往会让人感到困惑不解。本文将通过形象的比喻&#xff0c;帮助大家深入理解指针、解引用与指针变量的概念…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist

现象&#xff1a; android studio报错&#xff1a; [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决&#xff1a; 不要动CMakeLists.…...

java高级——高阶函数、如何定义一个函数式接口类似stream流的filter

java高级——高阶函数、stream流 前情提要文章介绍一、函数伊始1.1 合格的函数1.2 有形的函数2. 函数对象2.1 函数对象——行为参数化2.2 函数对象——延迟执行 二、 函数编程语法1. 函数对象表现形式1.1 Lambda表达式1.2 方法引用&#xff08;Math::max&#xff09; 2 函数接口…...

聚六亚甲基单胍盐酸盐市场深度解析:现状、挑战与机遇

根据 QYResearch 发布的市场报告显示&#xff0c;全球市场规模预计在 2031 年达到 9848 万美元&#xff0c;2025 - 2031 年期间年复合增长率&#xff08;CAGR&#xff09;为 3.7%。在竞争格局上&#xff0c;市场集中度较高&#xff0c;2024 年全球前十强厂商占据约 74.0% 的市场…...

游戏开发中常见的战斗数值英文缩写对照表

游戏开发中常见的战斗数值英文缩写对照表 基础属性&#xff08;Basic Attributes&#xff09; 缩写英文全称中文释义常见使用场景HPHit Points / Health Points生命值角色生存状态MPMana Points / Magic Points魔法值技能释放资源SPStamina Points体力值动作消耗资源APAction…...

HTTPS证书一年多少钱?

HTTPS证书作为保障网站数据传输安全的重要工具&#xff0c;成为众多网站运营者的必备选择。然而&#xff0c;面对市场上种类繁多的HTTPS证书&#xff0c;其一年费用究竟是多少&#xff0c;又受哪些因素影响呢&#xff1f; 首先&#xff0c;HTTPS证书通常在PinTrust这样的专业平…...

数据分析六部曲?

引言 上一章我们说到了数据分析六部曲&#xff0c;何谓六部曲呢&#xff1f; 其实啊&#xff0c;数据分析没那么难&#xff0c;只要掌握了下面这六个步骤&#xff0c;也就是数据分析六部曲&#xff0c;就算你是个啥都不懂的小白&#xff0c;也能慢慢上手做数据分析啦。 第一…...