0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

c++引用详细解说3

jf_78858299 来源:阿Q正砖 作者:阿Q正砖 2023-02-15 09:43 次阅读

但是临时变量在哪?

  • 如果 c 比较小(4/8 byte),一般是寄存器充当临时变量,例如eax
  • 如果 c 比较大,临时变量放在调用 add 函数的栈帧中,

最后将临时变量中的值赋值给ret

图:

图片

所有的传值返回都会生成一个拷贝

便于理解,看一下汇编

图片

看第四句话,这里是说,把 eax 中的值,拷贝到 ret 中。

而再函数调用返回时:

图片

这里是将 c 的值放到 eax 中的。

这也就印证了返回时,是以临时拷贝形式返回的,由于返回值是 int ,所以是直接用的 eax 寄存器

而不论这个函数结束后,返回的那个值会不会被销毁,都会创建临时变量返回,例如这段代码 :

int fun(){            static int n = 0;        n++;        return n;}
int main(){ int ret = fun(); cout << ret << endl; return 0;}

对于该函数,编译器仍然是创建临时变量返回;因为编译器不会对其进行特殊处理。

看一下汇编:

图片

仍然是放到 eax 寄存器中返回的。

埋个伏笔:你觉不觉的这个临时变量创建的很冤枉,明明这块空间一直存在,我却依然创建临时变量返回了?能不能帮它洗刷冤屈。

如果我改成引用返回会发生什么情况吗?

int& add(int a, int b){            int c = a + b;            return c;}int main(){            int ret = add(1, 2);            cout << ret << endl;            return 0;}

引用返回就是不生成临时变量,直接返回 c 的引用。而这里产生的问题就是 非法访问 。

造成的问题:

  • 存在非法访问,因为 add 的返回值是 c 的引用,所以 add 栈帧销毁后,会访问 c 位置空间,而这是读操作,不一定检查出来,但是本质是错的。
  • 如果 add 函数栈帧销毁,空间被清理,那么取 c 值时取到的就是随机值,取决于编译器的决策。

ps:虽然vs销毁栈帧没有清理空间数据,但是会二次覆盖

来看个有意思的:

图片

例如这里,当调用 add 函数之后,返回 c 的引用,接收返回值是用的ret相当于是 c 的引用,这时由于没有清理栈帧数据,所以打印3;

但是第二次调用,重新建立栈帧,由于栈帧大小相同,第二次建立栈帧可能还是在原位置,之前空间的数据被覆盖,继续运算,但是此时,ret 那块空间的值就被修改了,而这时没有接收返回值,但是原先的那块 c 的值被修改,所以打印出来 ret 是 30 。

所以使用引用返回时,一旦返回后,返回值的空间被修改,那么都可能会造成错误,使用要小心!

引用返回有一个原则:如果函数返回时,出了函数作用域,如果返回对象还在(还没还给系统),则可以使用引用返回,如果已经还给系统了,则必须使用传值返回。

它俩的区别就是一个生成拷贝,一个不生成拷贝。

而这时 static 修饰的静态变量不委屈了:

int& fun(){            static int n = 0;        n++;        return n;}

因为 static 修饰的变量在静态区,出了作用域也存在,这时就可以引用返回。

我们可以理解引用返回也有一个返回值,但是这个返回值的类型是 int& ,中间并不产生拷贝,因为返回的是别名。这就相当于返回的就是它本身。

有时引用返回可以发挥出意想不到的结果:

#include#define N 10typedef struct Array{            int a[N];            int size;}AY;
int& PostAt(AY& ay, int i){ assert(i < N); return ay.a[i];}int main(){ AY ay; PostAt(ay, 1); // 修改返回值 for (int i = 0; i < N; i++) { PostAt(ay, i) = i * 3; } for (int i = 0; i < N; i++) { cout << PostAt(ay, i) << ' '; } return 0;}

由于PostAt 的形参 ay 为 main 中 局部变量 ay的别名,所以 ay 一直存在;这时可以使用引用返回。

引用返回 减少了值拷贝 ,不比将其拷贝到临时变量中返回;并且由于是引用返回,我们也可以 修改返回对象 。

图片

总结提炼:如果出了作用域,返回变量(静态,全局,上一层栈帧,malloc等)仍然存在,则可以使用引用返回。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • C语言
    +关注

    关注

    180

    文章

    7597

    浏览量

    136133
  • C++
    C++
    +关注

    关注

    22

    文章

    2104

    浏览量

    73482
  • 面向对象
    +关注

    关注

    0

    文章

    64

    浏览量

    9978
收藏 人收藏

    评论

    相关推荐

    诺基亚3G机2730c功能详细解说

    诺基亚3G机2730c功能详细解说 随着3G在中国的快速普及,入门级市场的重要性也不断提升。近期,诺基亚
    发表于 02-23 09:05 5315次阅读

    Visual C++教程之C++的语言资料概述免费下载

    本文档详细介绍的是Visual C++教程之C++的语言资料概述免费下载主要内容包括了:1 从CC++的程序结构 ,2 程序书写规范,
    发表于 02-15 15:59 3次下载
    Visual <b class='flag-5'>C++</b>教程之<b class='flag-5'>C++</b>的语言资料概述免费下载

    C++程序设计教程之数据类型的详细资料说明

    本文档的主要内容详细介绍的是C++程序设计教程之数据类型的详细资料说明。1. 整型 ( int Types ) , 2.整型子类 ( sub-int Types ) , 3.浮点型
    发表于 02-21 17:18 3次下载
    <b class='flag-5'>C++</b>程序设计教程之数据类型的<b class='flag-5'>详细</b>资料说明

    C++程序设计教程之C++的初步知识的详细资料说明

    C++程序设计教程之C++的初步知识的详细资料说明包括了:1. 从CC++,2 . 最简单的C++
    发表于 03-14 14:48 31次下载
    <b class='flag-5'>C++</b>程序设计教程之<b class='flag-5'>C++</b>的初步知识的<b class='flag-5'>详细</b>资料说明

    C++程序设计教程之数组的详细资料说明

    本文档详细介绍的是C++程序设计教程之数组的详细资料说明主要内容包括了:1. 数组的概念,2. 一维数组的定义和引用3. 二维数组的定义和
    发表于 03-14 14:48 10次下载
    <b class='flag-5'>C++</b>程序设计教程之数组的<b class='flag-5'>详细</b>资料说明

    C++程序设计教程之指针的详细资料说明

    本文档详细介绍的是C++程序设计教程之指针的详细资料说明主要内容包括了:1. 指针的概念,2. 变量与指针,3. 数组与指针,4. 字符串与指针,5. 函数与指针,6. 返回指针值的函
    发表于 03-14 16:04 7次下载
    <b class='flag-5'>C++</b>程序设计教程之指针的<b class='flag-5'>详细</b>资料说明

    C++程序设计教程之C++工具的详细资料说明

    本文档的详细介绍的是C++程序设计教程之C++工具的详细资料说明主要内容包括了:1. 异常处理,2. 命名空间,3. 使用早期的函数库
    发表于 03-14 16:39 4次下载
    <b class='flag-5'>C++</b>程序设计教程之<b class='flag-5'>C++</b>工具的<b class='flag-5'>详细</b>资料说明

    C++程序设计的基础知识初步了解C++的资料免费下载

    本文档的主要内容详细介绍的是C++程序设计的基础知识初步了解C++的资料免费下载包括了:1 认识C++,2 C++的现状和发展,
    发表于 06-10 08:00 25次下载
    <b class='flag-5'>C++</b>程序设计的基础知识初步了解<b class='flag-5'>C++</b>的资料免费下载

    C++引用的使用场景

    C++引用的使用场景
    的头像 发表于 06-29 15:18 4034次阅读
    <b class='flag-5'>C++</b>:<b class='flag-5'>引用</b>的使用场景

    C++中的const和引用的讨论

    今天给大家分享一下这段时间学习c++的总结学习:c++里面的const关键字和引用
    的头像 发表于 12-24 15:35 815次阅读

    C++基础语法中的引用、封装和多态

    本期是C++基础语法分享的第六节,今天给大家来分享一下: (1)引用; (2)宏; (3)成员初始化列表; (4)封装; (5)继承; (6)多态; 引用 左值
    的头像 发表于 09-12 09:58 1288次阅读

    c++引用详细解说1

    C++C语言的继承,它可进行过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行以继承和多态为特点的面向对象的程序设计。
    的头像 发表于 02-15 09:40 546次阅读
    <b class='flag-5'>c++</b><b class='flag-5'>引用</b><b class='flag-5'>详细</b><b class='flag-5'>解说</b>1

    c++引用详细解说2

    C++C语言的继承,它可进行过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行以继承和多态为特点的面向对象的程序设计。
    的头像 发表于 02-15 09:43 481次阅读
    <b class='flag-5'>c++</b><b class='flag-5'>引用</b><b class='flag-5'>详细</b><b class='flag-5'>解说</b>2

    c++引用详细解说4

    C++C语言的继承,它可进行过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行以继承和多态为特点的面向对象的程序设计。
    的头像 发表于 02-15 09:43 490次阅读
    <b class='flag-5'>c++</b><b class='flag-5'>引用</b><b class='flag-5'>详细</b><b class='flag-5'>解说</b>4

    C++引用和指针

    之前的文章我们已经介绍了C++中的基本类型如int,bool和double等,除了基本类型C++还有一些更复杂的数据类型复合类型,所谓的复合类型就是通过其他类型定义的类型,本篇文章我们将会着重介绍C++的复合类型
    的头像 发表于 03-17 14:00 605次阅读