C++:函数重载和引用

hello,各位小伙伴,本篇文章跟大家一起学习C++:函数重载和引用,感谢大家对我上一篇的支持,如有什么问题,还请多多指教 !

文章目录

  • 函数重载
    • 1.函数重载的概念
    • 为什么C++支持函数重载
  • 引用
    • 引用的概念
    • 引用特性
    • 引用的使用场景
      • 1.做参数
      • 2.做返回值
    • 传值、传引用效率比较
    • 引用和指针的区别

函数重载

1.函数重载的概念

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

要注意是同一作用域,不同作用域可以同名,但是不属于函数重载

1.参数个数不同:

void f(int a)
{printf("%d\n",a);
}
void f(int a,int b)
{printf("%d %d\n",a,b);
}

2.参数类型不同:

void f(int a,int b)
{printf("%d %d\n",a,b);
}
void f(double a,double b)
{printf("%lf %lf\n",a,b);
}

3.参数类型顺序不同:

void f(int a,char b)
{printf("%d %c\n",a,b);
}
void f(char b,int a)
{printf("%d %c\n",a,b);
}

在函数重载时要注意可能会发生分歧,例如:

#include<iostream>
using namespace std;void f(int a)
{cout<<a<<endl;
}
void f(char a)
{cout<<a<<endl;
}
int main()
{int a = 1;f(a);return 0;
}

上述代码会报错,因为编译器不知道要调用哪一个f()函数,在传参时a可以隐式转换为char类型,这样就发生了分歧。

为什么C++支持函数重载

在C/C++中,一个程序要运行起来,需要经历以下几个阶段:预处理、编译、汇编、链接。
举个例子,a.cpp调用b.cpp中的Add()函数,那么链接器看到a.o调用Add()函数,但没有地址时,就会在去b.o寻找Add()的地址,然后链接在一起。
a.o、b.o分别为a.cpp、b.cpp预处理、编译、汇编后得到的文件

那么链接器怎么去找呢?
C++会使用已经修饰过的了Add()函数去寻找,怎么修饰与编译器有关,而C语言会直接使用Add这个函数名去寻找,那么两个一模一样的函数名,自然会发生分歧,使得编译器不知道走哪一个。

总的来说C++在链接时,会使用已经修饰过的函数名去寻找地址,函数参数个数不同、参数类型不同、参数类型顺序不同,修饰后的函数名自然不同,从而不会发生分歧。

!!!知道了为什么支持函数重载后,还有一点细节:返回值不同,构成函数重载吗?
答案是:不支持

如果两个函数函数名和参数是一样的,返回值不同是不构成重载的,因为调用时编译器没办
法区分。

引用

引用的概念

引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。

举个例子:陈明的别名是小明,但是小明就是陈明,指的是同一个人。
使用:类型& 引用变量名(对象名) = 引用实体;
例子:

int main()
{int a = 1;int& b = a;//   int       &   	b 	    =      a;//(引用类型)  &  (引用变量)	=  (引用实体)b = 3;cout<<a<<endl;printf("%p\n",&a);//表达式1printf("%p\n",&b);//表达式2return 0;
}

猜猜a的值为多少?没错,答案是3。
前面讲到,它和它引用的变量共用同一块内存空间,所以b指的就是ab的值改变,那么a当然会变,所以表达式1表达式2打印的结果一样,都是同一个地址。
在这里插入图片描述
注意:引用类型必须和引用实体是同种类型的
相信小伙伴们就能很容易理解,那么细节来了:

int main()
{const int a = 1;int& b = a;return 0;
}

这么些是否正确呢?相信聪明的小伙伴们一眼就看出答案:这么些是错误的。
const修饰a,那么a是不能改变的,而b并没有const修饰,所以b可以改变,也就是权限被放大了,本来a自身都不能改变,凭什么b可以。
再来:

int main()
{int a = 1;const int& b = a;return 0;
}

这么写b不能改变,a可以,权限被缩小,是可以的。
继续:

int main()
{int a = 1;const int* pa = &a;int*& b = pa;return 0;
}

很明显,这么写是错的,权限被放大了。
那么这个:

int main()
{int a = 1;int* const pa = &a;int*& b = pa;return 0;
}

这么写是正确的。

这两个声明之间存在重要的区别,这涉及到C++中指针和const关键字的使用。

  1. int* const pa = &a;

    • 这里 pa 是一个指针,它指向一个整数(int*)。
    • 关键字 const 出现在 * 前面,表示指针本身是常量,即指针一旦指向了某个地址之后,就不能再指向其他地址。
    • 也就是说,pa 是一个常量指针,它的值(即指向的地址)不可以被改变,但是它所指向的值可以被修改。
  2. const int* pa = &a;

    • 这里 pa 是一个指向常量整数的指针。
    • 关键字 const 出现在 int 前面,表示指针所指向的值是常量,即不能通过 pa 修改所指向的值。
    • 也就是说,pa 是一个指针,它可以指向任意整数,但通过 pa 只能读取所指向的值,而不能修改。

总结来说,int* const pa = &a; 表示 pa 是一个指针常量,而 const int* pa = &a; 表示 pa 是一个指向常量整数的指针。

引用特性

  1. 引用在定义时必须初始化(你总不能想到一个别名先放着,看到谁就给谁用吧)
int& a;//这么些是错的
  1. 一个变量可以有多个引用
int a = 1;
int& b = a;
int& c = a;
int& d = a;
  1. 引用一旦引用一个实体,再不能引用其他实体
int a = 1;
int& b = a;
int c = 1;
b = c;//这么些是错的

引用的使用场景

1.做参数

void Swap(int& left, int& right)
{int temp = left;left = right;right = temp;
}
int main()
{int a = 1;int b = 2;int& c = a;int& d = b;Swap(c,d);return 0;
}

2.做返回值

int& Test1()
{int n = 0;n++;return n;
}int main()
{int a = 0;int& b = a;b = Test1();cout << a;return 0;
}

传值、传引用效率比较

我们知道:

以值作为参数或者返回值类型,在传参和返回期间,函数不会直接传递实参或者将变量本身直接返回,而是传递实参或者返回变量的一份临时的拷贝,因此用值作为参数或者返回值型,效率是非常低下的,尤其是当参数或者返回值类型非常大时,效率就更低。

所以,传引用的效率比传值的效率更高,引用作为返回值比值作为返回值效率更高。

引用和指针的区别

语法概念上,引用是没有独立空间的,他就是引用实体的另一个名字,和其引用实体共用同一块空间。

int main()
{int a = 10;int& ra = a;cout<<"&a = "<<&a<<endl;cout<<"&ra = "<<&ra<<endl;return 0;
}

底层实现上实际是有空间的,因为引用是按照指针方式来实现的。

int main()
{int a = 10;int& ra = a;ra = 20;int* pa = &a;*pa = 20;return 0;
}

我们来看其汇编代码对比指针和引用
在这里插入图片描述
可以看出操作上是一样的。

引用和指针的不同点:

  1. 引用概念上定义一个变量的别名,指针存储一个变量地址。
  2. 引用在定义时必须初始化,指针没有要求
  3. 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何
    一个同类型实体
  4. 没有NULL引用,但有NULL指针
  5. 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32
    位平台下占4个字节)
  6. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
  7. 有多级指针,但是没有多级引用
  8. 访问实体方式不同,指针需要显式解引用,引用编译器自己处理
  9. 引用比指针使用起来相对更安全

好啦,这篇文章就到此结束了
所以你学会了吗?

好啦,本章对于C++:函数重载和引用的学习就先到这里,如果有什么问题,还请指教指教,希望本篇文章能够对你有所帮助,我们下一篇见!!!

如你喜欢,点点赞就是对我的支持,感谢感谢!!!
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机网络-HTTP相关知识-基础

HTTP基础 基本概念&#xff1a;HTTP是一种计算机之间交流通信的规范&#xff0c;它允许数据在两点之间传输&#xff0c;这个过程可以包括中转或接力。HTTP不仅仅包括文本&#xff0c;还可以包括图片、音频等超文本。状态码&#xff1a;HTTP状态码分为五类&#xff1a; 2xx&…

C++的 stack和queue 的应用和实现【双端队列的理解和应用】

文章目录 stack的理解和应用栈的理解栈的模拟实现string实现stackvector实现stack queue的理解和应用队列的理解队列的模拟实现 双端队列原理的简单理解deque的缺陷为什么选择deque作为stack和queue的底层默认容器STL标准库中对于stack和queue的模拟实现stack的模拟实现queue的…

深度学习pytorch好用网站分享

深度学习在线实验室Featurizehttps://featurize.cn/而且这个网站里面还有一些学习教程 免费好用 如何使用 PyTorch 进行图像分类https://featurize.cn/notebooks/5a36fa40-490e-4664-bf98-aa5ad7b2fc2f

木棍【dfs搜索优化】

木棒 题目描述 输入样例&#xff1a; 9 5 2 1 5 2 1 5 2 1 4 1 2 3 4 0输出样例&#xff1a; 6 5【思路】 优化 【AC代码】 #include <iostream> #include <algorithm> #include <cstring>using namespace std;const int N 70;int w[N], sum, length,…

C语言中的结构体:高级特性与扩展应用

前言 结构体在C语言中的应用不仅限于基本的定义和使用&#xff0c;还包含一些高级特性和扩展应用&#xff0c;这些特性和应用使得结构体在编程中发挥着更加重要的作用。 一、位字段&#xff08;Bit-fields&#xff09; 在结构体中&#xff0c;我们可以使用位字段来定义成员…

CMOS传输门与三态输出门电路

传输门&#xff08;TG&#xff09;的应用比较广泛&#xff0c;在数字电路和模拟电路中均有作用。 在数电中&#xff1a;作为基本单元电路构成各种逻辑电路&#xff1b;在模电中&#xff1a;可在取样-保持电路、斩波电路、数模转换器中传输模拟信号&#xff0c;所以又叫模拟开关…

AssetBundle在移动设备上丢失

1&#xff09;AssetBundle在移动设备上丢失 2&#xff09;Unity云渲染插件RenderStreaming&#xff0c;如何实现多用户分别有独立的操作 3&#xff09;如何在圆柱体类型的地图中编程玩家的输入 4&#xff09;Mixamo动画的根运动问题 这是第380篇UWA技术知识分享的推送&#xff…

【保姆级讲解如何安装与配置Node.js】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

Java中的网络编程(一)

一、网络编程概述 什么是计算机网络把不同区域的计算机&#xff08;广义&#xff09;通过通信设备和线路连接&#xff0c;可以实现数据的传输和共享的系统。实现不同计算机之间的练习&#xff0c;必须有介质连接。网络编程是干什么的聊天-->聊天软件 QQjava语言是支持网络间…

汽车EDI:如何与奔驰建立EDI连接?

梅赛德斯-奔驰是世界闻名的豪华汽车品牌&#xff0c;无论是技术实力还是历史底蕴都在全球汽车主机厂中居于领先位置。奔驰拥有多种车型&#xff0c;多元化的产品布局不仅满足了不同用户画像的需求&#xff0c;也对其供应链体系有着极大的考验。 本文将为大家介绍梅赛德斯-奔驰乘…

MySQL故障排查与生产环境优化

目录 引言 一、故障排查 1.1 故障一 1.2 故障二 1.3 故障三 1.4 故障四 1.5 故障五 1.6 故障六 1.7 故障七 1.8 故障八 1.9 故障九 1.10 故障十 1.11 故障十一 二、 生产环境优化 2.1 硬件优化 2.2 查询优化 总结 引言 MySQL是目前企业最常见的数据库之一&…

【Redis】Redis群集的三种模式(主从、哨兵、群集)

redis群集有三种模式&#xff0c;分别是主从同步/复制、哨兵模式、Cluster&#xff0c;下面会讲解一下三种模式的工作方式&#xff0c;以及如何搭建cluster群集 ●主从复制&#xff1a;主从复制是高可用Redis的基础&#xff0c;哨兵和集群都是在主从复制基础上实现高可用的。主…

MySQL、Oracle查看字节和字符长度个数的函数

目录 0. 总结1. MySQL1.1. 造数据1.2. 查看字符/字节个数 2. Oracle2.1. 造数据2.2. 查看字符/字节个数 0. 总结 databasecharbyteMySQLchar_length()length()Oraclelength()lengthB() 1. MySQL 1.1. 造数据 sql drop table if exists demo; create table demo (id …

软件架构复用

1.软件架构复用的定义及分类 软件产品线是指一组软件密集型系统&#xff0c;它们共享一个公共的、可管理的特性集&#xff0c;满足某个特定市场或任务的具体需要&#xff0c;是以规定的方式用公共的核心资产集成开发出来的。即围绕核心资产库进行管理、复用、集成新的系统。核心…

【Spring】SpringBoot整合MybatisPlus的基本应用

&#x1f4dd;个人主页&#xff1a;哈__ 期待您的关注 一、MybatisPlus简介 先来看一下官方的简介吧。 MyBatis-Plus &#xff08;简称 MP&#xff09;是一个 MyBatis的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;为 简化开发、提高效率而生。Myb…

【快速解决】python缺少了PyQt5模块的QtMultimedia子模块

目录 问题描述 问题原因 解决方法 成功示范 问题描述 Traceback (most recent call last): File "d:\桌面\python项目\DesktopWords-master\main.py", line 4, in <module> from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent ModuleNotFoundEr…

OpenCV入门例程:裁剪图片、模糊检测、黑屏检测

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 本例程运行环境为CentOS7&…

深入浅出 -- 系统架构之分布式常见理论概念

随着计算机科学和互联网的发展&#xff0c;分布式场景变得越来越常见&#xff0c;能否处理好分布式场景下的问题&#xff0c;成为衡量一个工程师是否合格的标准。本文我们介绍下分布式系统相关的理论知识&#xff0c;这些理论是我们理解和处理分布式问题的基础。 CAP理论 CAP…

NoSQL之 Redis配置

目录 关系数据库与非关系型数据库 关系型数据库&#xff1a; ●非关系型数据库 关系型数据库和非关系型数据库区别&#xff1a; &#xff08;1&#xff09;数据存储方式不同 &#xff08;2&#xff09;扩展方式不同 对事务性的支持不同 非关系型数据库产生背景 Redis简介…

智能停车场物联网远程监控解决方案

智能停车场物联网远程监控解决方案 智能停车场物联网远程监控解决方案是一种集成了现代物联网技术、大数据分析以及云计算等先进技术手段&#xff0c;对停车场进行全面智能化管理的综合系统。它通过实时感知、精准采集和高效传输各类停车数据&#xff0c;实现对停车场运营状态…