函数重载与引用

news2024/9/29 15:24:44

在这里插入图片描述

文章目录

    • 一、函数重载
      • 1. 重载规则
      • 2.重载列子
      • 3.函数名修饰规则
    • 二、引用
      • 1.本质
      • 2.特性
        • 1. 引用必须在定义时初始化
        • 2 . 一个变量可以有多个引用
        • 3 . 引用一旦引用一个实体,就不能引用其他实体
      • 3.引用例子
      • 4.引用的权限
      • 5.效率比较
      • 6.指针跟引用的区别

一、函数重载

函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或

类型顺序)不同,常用来处理实现功能类似数据类型不同的问题。

对于c语言是不允许重名函数的存在的,当函数名字相同时,就会报错。但是对于 c++ 可以。

因为C语言是根据函数名来去找函数的,可以简单的理解为C语言函数名就是地址

1. 重载规则

当函数重载条件满足如下三条时,则可以构成函数重载:

1.参数类型不同

2.参数个数不同

3.参数类型顺序不同

4、仅仅返回类型不同不足以称为函数重载的重载

5、需要在同一作用域下

2.重载列子

int add(int a, int b)
{
	return a + b;
}

void add(int a, float b)
{
	cout << "add(int a,float b)" << endl;
}

void add(float a, int b)
{
	cout << "add(float a,int b)" << endl;
}

float add(float a, float b)
{
	return a + b;
}

3.函数名修饰规则

对于函数重载后的函数,执行会不会变慢?不会,因为不是在运行时匹配,而是在编译时。

编译时如何进行识别?

对于C语言来说,就是依靠函数名去找函数的,如果函数名相同,则会冲突,因为不知道找哪个

对于C++来说,是通过函数名+参数类型+参数个数+参数顺序

二、引用

  1. 引用的基本概念

    • 引用是一个别名:引用是一个已存在变量的别名,通过引用可以访问原始变量的值。
    • 引用必须初始化:引用在创建时必须进行初始化,并且一旦初始化后,它将一直引用同一个变量。
  2. 使用引用的好处

    • 传递函数参数:通过引用传递参数,可以避免产生额外的复制开销,并且可以直接修改原始变量的值。
    • 返回函数结果:函数可以返回引用类型,以便返回引用指向的变量,而不是复制一个新的副本。
    • 在容器中使用引用:在使用STL容器时,使用引用可以避免元素的拷贝,提高效率。
  3. 引用与指针的比较

    • 引用与指针类似,但有一些关键区别。引用是一个别名,而指针是一个变量,可以指向其他变量。
    • 引用不能为空:引用在创建时必须进行初始化,并且不能重新赋值为空。
    • 引用使用更方便:相比指针,引用语法更简洁明了,更容易理解和使用。
  4. 常量引用

    • 常量引用是指对常量进行引用,即引用的变量不能被修改。
    • 常量引用可以绑定到临时对象,以便在函数调用中传递临时对象的值。
  5. 引用作为返回类型

    • 函数可以返回引用类型,在函数外部直接修改原始变量的值。
    • 注意返回局部变量的引用可能导致悬空引用,应避免这种情况。

1.本质

在这里插入图片描述
我们发现a和b不仅值相等,连地址也是相同的。而这就说明,b 就是 a ,在语法层面上,这里 b 并不是开辟的新空间,而是对原来的 a 取了一个新名称,叫做 b

相当于一块空间有多个名字一样,都是指向这块空间的

而如果这时候对 a 或 b 任意一个修改,那么 a 和 b 都会发生修改。
在这里插入图片描述

2.特性

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

在这里插入图片描述

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

在这里插入图片描述

3 . 引用一旦引用一个实体,就不能引用其他实体

int main()
{
	int a = 10;
	int& b = a;

	int c = 20;
	b = c;

	return 0;
}

那么这样又是什么意思呢

b引用了a,然后b=c是将c的值赋值给b
这就说明引用一旦引用一个实体,就不能引用其他实体,引用是不会发生改变的
在这里插入图片描述

3.引用例子

引用作为函数返回值
在Test函数当中定义了一个n,然后返回n的别名
在main函数当中用ret接受n的值
再打印ret,结果一直都是1

虽然Test()那块函数栈帧已经被销毁,但是我们使用int ret接受的n的值,并不是n
所以ret就是1

#include<iostream>

using namespace std;
int& Test()
{
	int n = 1;
	return n;
}
int main()
{
	int ret = Test();
	cout << ret << endl;
	cout << ret << endl;
	cout << ret << endl;
	cout << ret << endl;
	return 0;
}

在这里插入图片描述
然后我们将ret换为int & 来接受
这时候ret就是n的别名

n出了函数作用域就销毁了,函数栈帧销毁了,但是里面的东西还没有被覆盖,传引用返回给ret的话,ret话会去访问原来n那块空间的值
函数调用先传参,所以调用cout的时候,ret先去访问n原来的那块空间,得到n值之后再给cout
cout函数会建立一块函数栈帧空间在原来的Count上,所以打印出1
第二次调用cout的时候,ret再去访问n的时候,原来的空间已经被破坏了,所以这一次打印出来的是随机值

#include<iostream>

using namespace std;
int& Test()
{

	int n = 1;
	return n;
}
int main()
{

	int& ret = Test();
	cout << ret << endl;
	cout << ret << endl;
	cout << ret << endl;
	cout << ret << endl;
	return 0;
}

在这里插入图片描述

所以说如果用引用做返回值的话就需要确保返回的东西除了作用域是还存在的

4.引用的权限

#include<iostream>
using namespace std;
int main()
{
	int a = 1;
	int& b = a;
	const double& d = a;
	const int& c = 1;

	return 0;
}

对于类型转换,会先产生一个临时变量
然后临时变量具有常性,所以不可以被修改
所以double &d=a; 实际上并不是d去引用a
而是d去引用一个临时变量,所以需要+const去修饰

5.效率比较

#include <time.h>
struct A { int a[10000]; };
A a;
// 值返回
A TestFunc1() { return a; } // 拷贝
// 引用返回
A& TestFunc2() { return a; } // 不拷贝
void TestReturnByRefOrValue()
{
	// 以值作为函数的返回值类型
	size_t begin1 = clock();
	for (size_t i = 0; i < 100000; ++i)
		TestFunc1();
	size_t end1 = clock();
	// 以引用作为函数的返回值类型
	size_t begin2 = clock();
	for (size_t i = 0; i < 100000; ++i)
		TestFunc2();
	size_t end2 = clock();
	// 计算两个函数运算完成之后的时间
	cout << "TestFunc1 time:" << end1 - begin1 << endl;
	cout << "TestFunc2 time:" << end2 - begin2 << endl;
}

int main()
{
	TestReturnByRefOrValue();

	return 0;
}

由于传值返回要拷贝,所以当拷贝量大,次数多时,比较耗费时间;而传引用返回就不会,因为返回的就是别名
在这里插入图片描述

6.指针跟引用的区别

  1. 定义和初始化:

    • 指针:需要使用*来声明,可以指向不同的对象。
    • 引用:使用&来声明,必须在初始化时绑定到一个已存在的变量。
  2. 空值(Null):

    • 指针:可以具有空值(null),表示未指向有效的内存地址。
    • 引用:不存在空引用的概念,必须绑定到一个已存在的变量。
  3. 变量绑定:

    • 指针:可以在声明后重新指向其他变量。
    • 引用:在声明时就必须绑定到一个变量,并且无法改变绑定对象。
  4. 空间占用:

    • 指针:占用额外的内存空间,通常是4或8个字节。
    • 引用:不占用额外的内存空间,只是变量的别名。
  5. 空间操作:

    • 指针:可以进行算术运算和通过解引用操作符*访问所指的内存地址的值。
    • 引用:不能进行算术运算,直接访问绑定变量的值。
  6. 空间限制和安全性:

    • 指针:可以指向任意类型的对象,但需要注意空指针异常和野指针的问题。
    • 引用:只能用于已存在的变量,更加简洁和安全。
int main()
{
	int a = 10;
	
	int& ra = a;
	ra = 20;

	int* pa = &a;
	*pa = 20;
	return 0;
}

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

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

相关文章

我的创作纪念日 --- 鲁迅文学无聊版

机缘 ------从第一次使用CSDN这个网站到现在已经快四年了&#xff0c;我大抵是病了&#xff0c;2021年7月29日才心血来潮写下来了第一篇自己的博客&#xff0c;回顾起来&#xff0c;已经过去了2年。如此这般&#xff0c;断断续续的写过一些博客&#xff0c;但终归是心血来潮罢了…

【Docker】Docker的优势、与虚拟机技术的区别、三个重要概念和架构及工作原理详细讲解

前言 Docker 是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。 作者简介&#xff1a; 辭七七&#xf…

PS - Photoshop 实现涂抹功能 (橡皮擦、图章、吸管、画笔)

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/131997323 在 Photoshop 中&#xff0c;橡皮擦工具&#xff0c;以及吸管工具和画笔工具可以配合使用&#xff0c;实现涂抹功能&#xff0c;再通过…

第四届世界蜂疗大会在中国·重庆武隆盛大开幕

【39蜂疗网】记者 讯 7月25日至27日&#xff0c;“世界中联蜂疗专业委员会第五届学术年会暨第四届世界蜂疗大会、中国民族医药学会蜂疗分会2023年学术年会”在重庆武隆正式启幕。开幕式上&#xff0c;重庆市政府副市长但彦铮宣布开幕&#xff1b;人民英雄、中国工程院院士张伯礼…

QPainter绘制雷达界面

文章目录 功能实现定义的结构体定义的函数效果图gitee源码链接 功能实现 相较于上一版&#xff0c;这一版添加的功能有&#xff1a; 1、自适应窗口 2、扫描方式&#xff08;圆周扫描、扇形扫描&#xff08;指定起始角度和结束角度&#xff09;&#xff09; 3、扫描方向&#x…

WITH AS 的 sql语法是啥意思

WITH t1 AS ( select * from my_table_1 where age >30 ), t2 AS ( select * from my_table_2 where sex M ) select * from t1 inner join t2 on t1.id t2.t_id;WITH AS 的 sql语法是啥意思&#xff1f; WITH和AS是SQL语句中的关键字&#xff0c;用于创建临时命名的查询…

hcip——路由策略

要求&#xff1a; 基础配置 AR1 [R1]int g 0/0/0 [R1-GigabitEthernet0/0/0]ip add 12.0.0.1 24[R1-GigabitEthernet0/0/0]int g 0/0/1 [R1-GigabitEthernet0/0/1]ip add 14.0.0.1 24[R1]int loop0 [R1-LoopBack0]ip add 1.1.1.1 24[R1]rip 1 [R1-rip-1]vers 2 [R1-rip-1]net…

RS485/RS232自由转ETHERNET/IP网关profinet和ethernet区别

你是否曾经遇到过这样的问题&#xff1a;如何将ETHERNET/IP网络和RS485/RS232总线连接起来呢&#xff1f;捷米的JM-EIP-RS485/232通讯网关&#xff0c;自主研发的ETHERNET/IP从站功能&#xff0c;完美解决了这个难题。这款网关不仅可以将ETHERNET/IP网络和RS485/RS232总线连接起…

mysql(六)读写分离

目录 前言 一、概述 二、配置JAVA环境及安装阿米巴 三、配置阿米巴 四、测试 总结 前言 MySQL读写分离是一种常见的数据库架构设计模式&#xff0c;旨在提高系统的性能和可用性。它通过将读操作和写操作分离到不同的MySQL实例上来实现。 读写分离的原理是&#xff1a; 1. 主…

容器化安装环境EFK搭建

容器化安装环境 Docker中安装并启动ElasticSearch 前置配置 第一步&#xff1a;在宿主机上执行echo “net.ipv4.ip_forward1” >>/usr/lib/sysctl.d/00-system.conf 2.第二步&#xff1a;重启network和docker服务 [rootlocalhost /]# systemctl restart network &&…

Linux - PostgreSQL 适用于9.x 以上的 tar.gz 源码安装与理解 - 报错集锦

这里写目录标题 序言主要内容bash 配置文件个人理解关于初始化 PostgreSQL 数据库的理解 启动方法检查服务器是否在PostgreSQL中运行关闭 postgresql 数据库方法参考链接 序言 PostgreSQL 9.x 以下版本笔者没用过&#xff0c;具体操作看参考链接&#xff0c;笔者就不记录重复操…

2016年全国硕士研究生入学统一考试管理类专业学位联考写作试题——解析版

2016年1月真题&#xff1a; 四、写作&#xff1a;第56~57小题&#xff0c;共65 分。其中论证有效性分析30 分&#xff0c;论说文35分。 56、论证有效性分析&#xff1a; 分析下述论证中存在的缺陷和漏洞&#xff0c;选择若干要点&#xff0c;写一篇600字左右的文章&#xff0…

整数0 强制转化为指针

整数0强制转化为指针的巧用 在工程中看到以下代码&#xff1a; #define my_container_of(ptr,type,member) \ ((type*)((char *) (ptr) - (unsigned long)(&((type*)0)->member))) ->的优先级高于&。 因此 &((type*)0)->member)的解…

Zynq-Linux移植学习笔记之62- PL挂载复旦微flash

1、背景介绍 现在为了全国产化需要&#xff0c;之前所有的进口flash全部要换成国产flash 2、复旦微flash型号 其中EFM25QU256和EFM25QL256对标winbond的w25q256 nor flash 3、FPGA设置 复旦微flash只支持单线模式&#xff0c;当使用PL侧的IP核访问时&#xff0c;需要设置模式…

正在运行中的宝塔项目扩容阿里云购买服务器云盘(数据盘) 挂载流程

阿里云购买服务器云盘(数据盘) 正在运行中的宝塔项目 挂载流程 注意一定要进行阿里云的快照备份 在进行操作 不然丢失数据后就很无奈 注意一定要进行阿里云的快照备份 在进行操作 不然丢失数据后就很无奈 注意一定要进行阿里云的快照备份 在进行操作 不然丢失数据后就很无奈 …

6G内存运行Llama2-Chinese-7B-chat模型

6G内存运行Llama2-Chinese-7B-chat模型 Llama2-Chinese中文社区 第一步&#xff1a; 从huggingface下载 Llama2-Chinese-7b-Chat-GGML模型放到本地的某一目录。 第二步&#xff1a; 执行python程序 git clone https://github.com/Rayrtfr/llama2-webui.gitcd llama2-web…

PCIe基础知识

PCI基础知识 PCI总线的组成&#xff1a;HOST桥、PCI桥、PCI设备 PCI采用的是树型拓扑结构&#xff0c;每一个PCI device相当于树的一个结点或者叶子&#xff0c;对整个PCI Bus的遍历可以采用遍历树的算法&#xff0c;在对树进行遍历之后&#xff0c;可以获得整个PCI Bus的资源需…

海外抖音Tiktok强势来袭,有些人半年赚别人十倍工资

TikTok作为一款流行的短视频社交应用程序&#xff0c;确实在全球范围内取得了很大的成功。许多人通过在TikTok上分享有趣、创意或有吸引力的视频内容&#xff0c;获得了广泛的关注和认可。一些用户甚至能够通过TikTok赚取高额的收入&#xff0c;远远超过传统职业所能获得的工资…

[C++笔记]二叉搜索树

BSTree.h #pragma oncenamespace key {template<class K>//这里习惯用K而不是T&#xff0c;keystruct BSTreeNode {BSTreeNode<K>* _left;BSTreeNode<K>* _right;K _key;BSTreeNode(const K& key):_left(nullptr), _right(nullptr), _key(key){}};templ…

Hbuilder折叠代码时显示最后一行

之前写pc端代码时&#xff0c;都是使用vscode&#xff0c;里面的折叠代码&#xff0c;都是将开头和尾部中间的内容折叠起来&#xff0c;这样复制或者删除操作代码时&#xff0c;都很顺手&#xff0c;但是最近要用Hbuilder写移动端&#xff0c;它默认的折叠代码方式&#xff0c;…