c++ 函数的值传递,引用传递 和 引用返回的探索

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

前言

C++的函数参数和返回分为按值传递和按引用传递,应用到类上面,会涉及到类的 赋值操作 复制函数 构造函数 析构函数

虽然java开发了两年,但对我而言c++我还只是一个初学者.c++还有很多陌生的特性需要自己亲自探索.这里用实际例子作为探索,不对之处望斧正:

由于基本类型和类在函数里的生命周期是相似的,这里以一个自定义类为例,一是为了方便观察对象的地址,二是可以了解每一步会涉及到类的哪些生命周期:

类的定义

#include <iostream>using std::cout;
using std::endl;
using std::string;class A {
public:A() {cout << "构造函数:" << this << endl;}A(const A &input) {cout << "复制函数:" << this << endl;}// 复制直接返回 *this 本身A &operator=(const A &input) {cout << "赋值函数:" << this << endl;// this 其实是个新的内存空间,啥值都没设置return *this;}~A() {cout << "析构函数:" << this << endl;}
};

值传递 和 返回值

我们定义一个值传递的函数,返回的也是值

A test1(A a) {cout << "test1函数体:&a=" << &a << endl;return a;
}

执行main函数如下

int main() {cout << "--- 对象创建 ---" << endl;A a;cout << "--- 函数调用 ---" << endl;A b = test1(a);cout << "--- 结束 ---" << endl;return 0;
}

执行结果

--- 对象创建 ---
构造函数:0x7fff5ed19768
--- 函数调用 ---
复制函数:0x7fff5ed19750
test1函数体:&a=0x7fff5ed19750
复制函数:0x7fff5ed19758
析构函数:0x7fff5ed19750
--- 结束 ---
析构函数:0x7fff5ed19758
析构函数:0x7fff5ed19768

由此可见,在函数的栈帧里,对入参a进行了一次复制(0x7fff5ed19750),而在返回栈帧里的input时,又会对函数结果复制生成一个临时变量(0x7fff5ed19758),并回收栈帧里的input. 函数结束会把临时变量返回给b,至此结束函数调用.也就是说,这里函数的入参和返回各涉及一次复制操作

函数入参和返回使用引用

我们对test1做出修改,将入参和返回变更为引用,如下

A &test1(A &a) {cout << "test1函数体:&a=" << &a << endl;return a;
}

将main中的b也变更为引用如下:

int main() {cout << "--- 对象创建 ---" << endl;A a;cout << "--- 函数调用 ---" << endl;A &b = test1(a);cout << "--- 结束 ---" << endl;return 0;
}

执行结果:

--- 对象创建 ---
构造函数:0x7fff56dd5768
--- 函数调用 ---
test1函数体:&a=0x7fff56dd5768
--- 结束 ---
析构函数:0x7fff56dd5768

因为是引用函数栈帧内并没有进行任何复制操作

函数返回的临时变量探索

如果函数不返回引用,或b不是引用,仍然会产生临时变量

A test1(A &a) {cout << "test1函数体:&a=" << &a << endl;return a;
}
A& test2(A &a) {cout << "test2函数体:&a=" << &a << endl;return a;
}
int main() {cout << "--- 对象创建 ---" << endl;A a;cout << "--- 函数调用1 ---" << endl;A b1 = test1(a);cout << "--- 函数调用2 ---" << endl;A b2 = test2(a);cout << "--- 结束 ---" << endl;return 0;
}

返回结果如下

--- 对象创建 ---
构造函数:0x7fff5daae758
--- 函数调用1 ---
test1函数体:&a=0x7fff5daae758
复制函数:0x7fff5daae748
--- 函数调用2 ---
test2函数体:&a=0x7fff5daae758
复制函数:0x7fff5daae740
--- 结束 ---
析构函数:0x7fff5daae740
析构函数:0x7fff5daae748
析构函数:0x7fff5daae758

test1和test2的区别只在于返回结果是否为引用,但在栈帧外都产生了临时变量

赋值操作探索

这里再对赋值做探索,这次把以上3中情况合在一起为例,如下

A &test1(A &a) {cout << "test1函数体:&a=" << &a << endl;return a;
}
A &test2(A a) {cout << "test2函数体:&a=" << &a << endl;return a;
}
A test3(A a) {cout << "test2函数体:&a=" << &a << endl;return a;
}
int main() {cout << "--- 对象创建 ---" << endl;A a;cout << "--- 函数调用1 ---" << endl;a = test1(a);cout << "--- 函数调用2 ---" << endl;a = test2(a);cout << "--- 函数调用3 ---" << endl;a = test3(a);cout << "--- 结束 ---" << endl;return 0;
}

输出结果

--- 对象创建 ---
构造函数:0x7fff513b6748
--- 函数调用1 ---
test1函数体:&a=0x7fff513b6748
赋值函数:0x7fff513b6748
--- 函数调用2 ---
复制函数:0x7fff513b6738
test2函数体:&a=0x7fff513b6738
赋值函数:0x7fff513b6748
析构函数:0x7fff513b6738
--- 函数调用3 ---
复制函数:0x7fff513b6728
test2函数体:&a=0x7fff513b6728
复制函数:0x7fff513b6730
赋值函数:0x7fff513b6748
析构函数:0x7fff513b6730
析构函数:0x7fff513b6728
--- 结束 ---
析构函数:0x7fff513b6748
  • test1 相当于a=a;除了将值赋值给自己外栈帧没有额外操作,这个很好理解
  • test2 对入参进行复制,并把复制的入参值赋值给a并在函数栈帧结束后回收入参
  • test3 比较复杂,会复制入参和临时变量,并把临时变量赋值给a,赋值结束后对入参和临时变量进行回收

转载于:https://my.oschina.net/tdONEmadao/blog/915677

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

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

相关文章

GCD的部分总结

GCD是基于C语言的底层API,用Block定义任务用起来非常灵活便捷. GCD的基本思想是就将操作放在队列中去执行 (1)操作使用Blocks定义(2)队列负责调度任务执行所在的线程以及具体的执行时间(3)队列的特点是先进先出(FIFO)的&#xff0c;新添加至对列的操作都会排在队尾关于多线程的…

将bgr彩色矩阵归一化到0-255之间 【RGB image normalization】

参考下面文章&#xff0c;可以使用normalize 函数。 https://blog.csdn.net/kuweicai/article/details/78988886 对于彩色rgb图像&#xff0c;也可以直接使用以上函数, 参考 https://devtalk.nvidia.com/default/topic/1042100/rgb-image-normalization/?offset8 image cv2…

多线程编程2-NSOperation

本文目录 前言一、NSInvocationOperation二、NSBlockOperation三、NSOperation的其他用法四、自定义NSOperation回到顶部前言 1.上一讲简单介绍了NSThread的使用&#xff0c;虽然也可以实现多线程编程&#xff0c;但是需要我们去管理线程的生命周期&#xff0c;还要考虑线程同步…

python图片显示英文字符_python如何解析字符串中出现的英文人名?

这里有四个例子&#xff0c;结果来自google scholarstr1 "Jakes, William C., and Donald C. Cox. Microwave mobile communications. Wiley-IEEE Press, 1994."str2 "Schlegel, David J., Douglas P. Finkbeiner, and Marc Davis. \"Maps of dust infra…

闪回表操作语法+使用闪回删除

闪回表操作语法 flashback table 【 schema.】 table_name to {【before drop 【rename to new_table_name】 】|【scn | timestamp 】】 expr 【enable | disable 】 triggers}: 参数说明&#xff1a; schema&#xff1a;用户模式 before drop&#xff1a;表示恢复到删除…

在现有的python环境下创建另一个python版本【亲测有效】

比如&#xff0c;你现在的python环境是3.6&#xff0c;想要使用一个3.5&#xff0c;可以在anaconda环境下使用conda虚拟环境。 第一步&#xff1a; conda create -n py35 【创建Py35虚拟环境】 第二步&#xff1a; 进入环境 activate py35 第三步&#xff1a; 升级或者降…

时间戳

我发现&#xff0c;我在本站公布的文章&#xff0c;url 最后一段都是 134 开头的一串数字。一開始并没在意&#xff0c;仅仅想当然以为是程序随机生成的。 昨天跟程序作者交谈的过程中无意问起&#xff0c;他说这是代表时间的。刚才訪问 GoAgent 项目时发现&#xff0c;其作者 …

欧拉函数 - HDU1286

欧拉函数的作用&#xff1a; 有[1,2.....n]这样一个集合&#xff0c;f(n)这个集合中与n互质的元素的个数。欧拉函数描述了一些列与这个f(n)有关的一些性质&#xff0c;如下&#xff1a; 1、令p为一个素数&#xff0c;n p ^ k&#xff0c;则 f(n) p ^ k - p ^ (k-1) 2、令m&…

其中一个页签慢_渭南提升一个大专学历的有效方法

渭南提升一个大专学历的有效方法&#xff0c;宏德教育&#xff0c;目前已形成以高等学历教育为特色王牌&#xff0c;职称考评、企业内训为辅助的强力优势品牌。渭南提升一个大专学历的有效方法&#xff0c; 获得发明专利或实用新型专利&#xff0c;且已实施取得效益。出版本专业…

《收集苹果》 动态规划入门

问题描写叙述 平面上有N*M个格子&#xff0c;每一个格子中放着一定数量的苹果。你从左上角的格子開始&#xff0c;每一步仅仅能向下走或是向右走&#xff0c;每次走到一个格子上就把格子里的苹果收集起来&#xff0c;这样下去&#xff0c;你最多能收集到多少个苹果。 输入&…

Xamarin XAML语言教程通过ProgressTo方法对进度条设置

2019独角兽企业重金招聘Python工程师标准>>> Xamarin XAML语言教程通过ProgressTo方法对进度条设置 在ProgressBar中定义了一个ProgressTo方法&#xff0c;此方法也可以用来对进度条当前的进行进行设置&#xff0c;ProgressTo与Progress属性的不同之处在于ProgressT…

Radar Installation

题目链接&#xff1a;http://acm.hust.edu.cn/vjudge/problem/visitOriginUrl.action?id27586 题意&#xff1a; 在海岸线上摆放雷达并限定雷达覆盖半径d&#xff0c;再以海岸线为轴&#xff0c;给定海上岛屿坐标&#xff0c;求至少需要多少雷达可以覆盖所以岛屿&#xff0c;如…

win7 + vs2015+ matlab2016a + python3.5安装matcaffe cpu版本

参考&#xff1a; 1. caffe-windows直接安装版---编译后的Release 2.安装Windows10 和环境下的caffe&#xff08;新版&#xff09; 3.win10vs2015编译caffe的cpu debug版本、部署matcaffe 主要的方法参考文献3. 当前caffe-windows仅支持python2.7和3.5 要注意的是&#…

python调用 matlab库_python调用matlab的搜索结果-阿里云开发者社区

2018python技术问答集锦&#xff0c;希望能给喜欢python的同学一些帮助小编发现问答专区中有很多人在问关于python的问题&#xff0c;小编把这些问题汇总一下&#xff0c;希望能给喜欢python的大家一些启示和帮助本帖不定期更新&#xff0c;喜欢的可以收藏哦python可能替代Java…

h5新特性

 CSDN博客 Gane_ChengHTML5新特性浅谈 发表于2016/10/17 21:25:58 7809人阅读 分类&#xff1a; 前端 转载请注明出处&#xff1a; http://blog.csdn.net/gane_cheng/article/details/52819118 http://www.ganecheng.tech/blog/52819118.html &#xff08;浏览效果更好…

打勾显示输入的密码 --EditText与setTransformationMethod

实现目标: 实现原理: 为CheckBox添加一个监听器事件; 实现的源码: package edu.cquptzx.showPassword; import android.app.Activity; import android.os.Bundle; import android.text.method.HideReturnsTransformationMethod; import android.text.method.PasswordTransforma…

mysql日期截取年月_摄影大赛丨“我遇见最美的光”第五届全国医务人员摄影大展 截稿日期2020年8月15日...

截稿日期2020年8月15日《“我遇见最美的光”第五届全国医务人员摄影大展》欣赏过山川壮丽&#xff0c;瞻仰过造化旖旎&#xff0c;敬重于生命伟大&#xff0c;感动于英雄凯旋……由《大众摄影》主办&#xff0c;正大天晴药业集团股份有限公司、《中国卫生影像》杂志协办的“我遇…

iframe子页面内刷新父页面中另一个iframe子页面

框架页面如下&#xff1a; <div id"aa" style"float: left; height: 500px; border-right-style: solid; border-right-color: #CCCCFF; border-right-width: 2px;"> <IFRAME id"tree" name"tree" src"/ScienProject…

Pytorch的C++接口实践

Pytorch1.1版本已经提供了相对稳定的c接口&#xff0c;网上也有了众多的资料供大家参考&#xff0c;进行c的接口的初步尝试。 可以按照对应的选项下载&#xff0c;下面我们要说的是&#xff1a; 如何利用已经编译好的官方libtorch库和其他的opencv库等联合编写应用&#xff1f…

一次惨痛的装机经历

最近不小心把我的联想一体机电脑系统搞坏了&#xff0c;就不得不重装系统&#xff0c;之前的系统是win7&#xff0c;于是开始的时候想着直接装win10&#xff0c;升级一下系统。但是装的过程中总是卡在了win10的正在准备系统中&#xff0c;进度环不转了。后来转了多次都不行&…