C++语法应用:从return机制看返回指针,返回引用
前言
编程是极其注重实践的工作,学习的同时要伴随代码
引入
此前对返回指针和引用有一些纠结,从return角度来观察发生了什么。
return机制
函数中return表示代码结束,如果return后面有其他代码将不被执行。
return发生了值转移,return后面的变量或者值被复制到新变量(地址)中,然后栈空间被释放。
下面以一段代码演示return,以及查看返回指针和引用,发生了什么
#include<iostream>
using namespace std;int* fun_pt(int tmp); //返回指针
int& fun_ref(int tmp); //返回引用,return值
int& ret_ref(int tmp); //返回引用,return引用int main(void) {int* a = fun_pt(3);cout << "指针指向数据为:" << *a << endl; //返回临时变量指针,得不到准确结果cout << "=============" << endl;int b = fun_ref(3); //返回临时变量引用,值接收,得到准确结果cout << "引用指向数据为:" <<b << endl;cout << "=============" << endl;int c = ret_ref(3); //返回临时变量引用,值接收,得到准确结果cout << "引用指向数据为:" << c << endl;int& d = ret_ref(4); //返回临时变量引用,引用接收,得不到准确结果cout << "引用指向数据为:" << d << endl;
}int* fun_pt(int tmp) {int a = tmp;return &a; //返回临时变量地址
}int& fun_ref(int tmp) {int a = tmp;return a; //返回临时变量的引用,return值
}int& ret_ref(int tmp) {int& a = tmp;return a; //返回临时变量的引用,return引用
}
测试结果如下:
指针指向数据为:-858993460
=============
引用指向数据为:3
=============
引用指向数据为:3
引用指向数据为:1923686208
说明:
1.return后面跟变量,值或者引用,表达意思是一样的。
因为return表示把表达式赋值给返回类型。例如fun_pt的return &a;表示int *(变量名)接收&a.在main()函数中的int* a = fun_pt(3);表示指针变量a接收。此时引用在等号右边,在上一篇对引用分析的帖子C++语法应用:返回指向局部变量的引用__使用new分配空间(不推荐)-CSDN博客中提到过:引用在等号右边时,相当于解引用指针(取值),所以在fun_ref和ret_ref两个函数中表示的意思是一样的:返回整型值a。
2.返回临时变量的指针,得不到正确结果。
在return &a时,将计算好的a地址赋值给int* 类型变量a(两个a不一样,一个是栈区的临时变量,一个是main函数中的临时变量),这个动作完成后,栈区内存被释放。当下一句*a表示要取整型指针a指向的数据时,原有数据已不存在,所以得到结果是一个看起来很大的数字。
3.返回局部变量的引用,能否得到正确结果取决于用变量接收还是引用接收
1>当返回的引用类型采用变量接收时,发生了值转移,得到的结果是正确的。代码中
int b = fun_ref(3);
int c = ret_ref(3);
说明了这一点。而且他们的好处是return时没有使用数据副本,节约了内存空间。
2>当返回的引用类型使用引用接收时,相当于临时变量的指针返回给引用,所以再次使用该引用时得不到正确结果。代码中
int& d = ret_ref(4);
cout << "引用指向数据为:" << d << endl; //内存已被释放,d取到的值错误
说明了这一点。
使用对象测试
再用类试一下这个观点是否正确。声明一个类
class Demo {int age;
public:Demo(int ag):age(ag){}int get_age() { return age; }void set_age(int ag) { age = ag; }
};
声明一个全局函数,为了看起来更清晰,不用OOP写成对象方法(写成对象方法也不会错,结果不变)
Demo& fun_demo(int age) {Demo demo(age); //生成临时对象return demo; //返回该对象
}
测试代码
int main(void) {Demo demo = fun_demo(18); //变量接收,结果正确cout << "你设置的对象的年龄为:" << demo.get_age()<< endl; Demo& demo2 = fun_demo(18); //引用接收,结果错误cout << "你设置的对象的年龄为:" << demo2.get_age()<< endl;
}
运行结果:
你设置的对象的年龄为:18
你设置的对象的年龄为:32759
结论与前面一致。
顺便提一下:在构造函数中常用的,传入引用,返回该引用做属性。这是一种很常见的---使用引用控制传入对象的方法。和这里的代码不矛盾,相当于引用接收引用,而使用引用可以修改原值。
小结
在实践中发现了<C++ Prime Plus>6th Edition中一个描述不完整的地方。书中描述:不要返回局部变量或临时变量的引用。而实际情况是:可以返回局部变量或临时变量的引用,必须用变量接收。
相关文章:
C++语法应用:从return机制看返回指针,返回引用
前言 编程是极其注重实践的工作,学习的同时要伴随代码 引入 此前对返回指针和引用有一些纠结,从return角度来观察发生了什么。 return机制 函数中return表示代码结束,如果return后面有其他代码将不被执行。 return发生了值转移,return后面的…...
Linux5-echo,>,tail
1.echo命令 echo是输出命令,类似printf 例如:echo "hello world",输出hello world echo pwd,输出pwd的位置。是键盘上~ 2.重定向符> >> >指把左边内容覆盖到右边 echo hello world>test.txt >…...

sqlgun靶场训练
1.看到php?id ,然后刚好有个框,直接测试sql注入 2.发现输入1 union select 1,2,3#的时候在2处有回显 3.查看表名 -1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schemadatabase()# 4.查看列名…...

简化登录流程,助力应用建立用户体系
随着智能手机和移动应用的普及,用户需要在不同的应用中注册和登录账号,传统的账号注册和登录流程需要用户输入用户名和密码,这不仅繁琐而且容易造成用户流失。 华为账号服务(Account Kit)提供简单、快速、安全的登录功能,让用户快…...

【研发日记】嵌入式处理器技能解锁(六)——ARM的Cortex-M4内核
文章目录 前言 背景介绍 指令集架构 ARM起源 ARM分类 Cortex-M4 内核框架 指令流水线 实践应用 总结 参考资料 前言 见《【研发日记】嵌入式处理器技能解锁(一)——多任务异步执行调度的三种方法》 见《【研发日记】嵌入式处理器技能解锁(二)——TI C2000 DSP的SCI(…...

深度学习经典模型之T5
T5(Text-to-Text Transfer Transformer) 是继BERT之后Google的又外力作,它是一个文本到文本迁移的基于Transformer的NLP模型,通过将 所有任务统一视为一个输入文本并输出到文本(Text-to-Text)中,即将任务嵌入在输入文本中,用文本的…...

10.第二阶段x86游戏实战2-反编译自己的程序加深堆栈的理解
免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 本次游戏没法给 内容参考于:微尘网络安全 工具下载: 链接:https://pan.baidu.com/s/1rEEJnt85npn7N38Ai0_F2Q?pwd6tw3 提…...

ARM总复习
1.计算机的组成 输入设备 输出设备 存储设备 运算器 控制器、总线 2.指令和指令集 2.1 机器指令 机器指令又叫机器码,在运算器内部存在各种运算电路,当处理器从内存中获取一条机器指令,就可以按照指令让运算器内部的指定的运算电路进行运…...

使用ENVI之大气校正(下)
再根据遥感影像的拍摄时间将Flight ate与Flight Time GMT (H:M:SS)填写,如要查询按如下方法 这里按照表中的内容修改 根据影像范围的经纬度与拍摄时间更改Atmospheric Model,更改完成后点击Multispectral Settings...在跳出的界面中选择GUI再点击Default…...
C++(学习)2024.9.18
目录 C基础介绍 C特点 面向对象的三大特征 面向对象与面向过程的区别 C拓展的非面向对象的功能 引用 引用的性质 引用的参数 指针和引用的区别 赋值 键盘输入 string字符串类 遍历方式 字符串与数字转换 函数 内联函数 函数重载overload 哑元函数 面向对象基…...
认知小文2《成功之路:习惯、学习与实践》
内容摘要: 在这个充满机遇的时代,成功不再是偶然,而是可以通过培养良好习惯、持续学习和实践来实现的目标。 一、肌肉记忆:技能的基石 成功往往需要像运动员一样,通过日复一日的练习来形成肌肉记忆。无论是健身…...

【数据仓库】数据仓库层次化设计
一、基本概念 **1. RDS(RAW DATA STORES,原始数据存储)** RDS作为原始数据存储层,用于存储来自各种源头的未经处理的数据。这些数据可能来自企业内部的业务系统、外部数据源或各种传感器等。RDS确保原始数据的完整性和可访问性&…...

【DAY20240918】03教你轻松配置 Git 远程仓库并高效推送代码!
文章目录 前言 git diff一、远程仓库?1、在 Gitee 上新建仓库:2、Git 全局设置:3、添加远程仓库:4、推送本地代码到远程仓库:5、输入用户名和密码:6、后续推送: 二、全情回顾三、参考 前言 git …...
从IPC摄像机读取视频帧解码并转化为YUV数据到转化为Bitmap
前言 本文主要介绍根据IPC的RTSP视频流地址,连接摄像机,并持续读取相机视频流,进一步进行播放实时画面,或者处理视频帧,将每一帧数据转化为安卓相机同格式数据,并保存为bitmap。 示例 val rtspClientListener = object: RtspClient.RtspClientListener {override fun …...

LeetCode 面试经典 150 题回顾
目录 一、数组 / 字符串 1.合并两个有序数组 (简单) 2.移除元素 (简单) 3.删除有序数组中的重复项 (简单) 4.删除有序数组中的重复项 II(中等) 5.多数元素(简单&am…...

【网络安全的神秘世界】渗透测试基础
🌝博客主页:泥菩萨 💖专栏:Linux探索之旅 | 网络安全的神秘世界 | 专接本 | 每天学会一个渗透测试工具 渗透测试基础 基于功能去进行漏洞挖掘 1、编辑器漏洞 1.1 编辑器漏洞介绍 一般企业搭建网站可能采用了通用模板ÿ…...

【重学 MySQL】二十九、函数的理解
【重学 MySQL】二十九、函数的理解 什么是函数不同 DBMS 函数的差异函数名称和参数功能实现数据类型支持性能和优化兼容性和可移植性 MySQL 的内置函数及分类单行函数多行函数(聚合函数)使用注意事项 什么是函数 函数(Function)在…...
MySQL5.7主从复制搭建-gtid方式
环境准备 1、主机名和和IP地址如下 10.0.0.51 db01.ljbb.com 10.0.0.52 db02.ljbb.com 10.0.0.53 db03.ljbb.com2、配置文件 db01 [mysqld] usermysql basedir/app/mysql datadir/data/mysql/data socket/tmp/mysql.sock server_id51 port3306 secure-file-priv/tmp autoco…...
golang学习笔记22——golang微服务中数据竞争问题及解决方案
推荐学习文档 golang应用级os框架,欢迎stargolang应用级os框架使用案例,欢迎star案例:基于golang开发的一款超有个性的旅游计划app经历golang实战大纲golang优秀开发常用开源库汇总想学习更多golang知识,这里有免费的golang学习笔…...

yolo训练出现Could not load library libcudnn_cnn_train.so.8问题及解决方法
问题场景: 训练yolov5或者yolov8时候会报错: Could not load library libcudnn_cnn_train.so.8. Error: /usr/local/cuda-12.1/lib64/libcudnn_cnn_train.so.8: uined symbol: _ZN5cudnn3cnn34layerNormFwd_execute_internal_implERKNS_7backend11Vari…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...

XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...

51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...

srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...

NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...