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

前言

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

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

  1. C++ 函数参数 值传递与引用传递

    以前我们在C语言中函数参数传递过程中,如果我们想要让当A函数作用域中的变量经过B函数处理之后的数值仍然在A函数中生效,这个时候函数参数的传递时需要引用方式去传递,方式如下: #include < ...

  2. python参数传递方法_深入理解python中函数传递参数是值传递还是引用传递

    python 的 深入理解python中函数传递参数是值传递还是引用传递 目前网络上大部分博客的结论都是这样的: Python不允许程序员选择采用传值还是传 引用.Python参数传递采用的肯定是&q ...

  3. php函数间参数传递(值传递/引用传递)

    为什么80%的码农都做不了架构师?>>>    函数间的参数传递包括值传递和引用传递. php:函数间的参数传递 1.值传递 复制代码代码如下: <?php  function ...

  4. js中函数传递参数,究竟是值传递还是引用传递?

    记住真理: js函数传递参数,不管是简单数据类型,还是引用数据类型,都是值传递!! 下面是js红包书里面的例子: function setName(obj) { obj.name = "Ni ...

  5. python 值传递还是引用传递_python函数是值传递还是引用传递

    在网上看python的基础知识,看到函数这一章的时候,看到这么一段话: 所有参数(自变量)在Python里都是按引用传递.如果你在函数里修改了参数,那么在调用这个函数的函数里,原始的参数也被改变了. ...

  6. 如何引用传递参数从一个函数中得到多个返回值

    2019独角兽企业重金招聘Python工程师标准>>> 通过"引用"传递参数的方法从一个函数中得到多个返回值.就像三元运算符一样,大部分受过正式编程训练的程序员都 ...

  7. Javascript 之《函数传参到底是值传递还是引用传递》

    前言 这个问题其实困惑了我好久,但是在实际使用中总是得过且过,不想去深究.由于这种态度,在学习 Javascript 过程中,水平一直都是出于半桶水状态,很多概念和原理似懂非懂,模糊不清. 所以,写了 ...

  8. Java 函数传递对象是引用传递还是值传递?

    class A {int val; }public class main {public static void fun(A a, A b) {// a.val = 6;a = b;}public s ...

  9. python函数参数的引用传递_Python初学者笔记(八):函数参数的值传递和引用传递...

    函数参数的值传递和引用传递 像我们最熟悉的 C 语言,再写函数参数的同时需要规定函数参数到底是值传递还是引用传递.引用传递导致该参数在函数内的修改出了函数之外也会生效,值传递所有的修改都不会体现到函数 ...

  10. c语言 函数参数传递 值传递,c语言中函数参数的三种传递方式——值传递、指针传递、引用传递...

    函数参数有三种传递方式值传递.指针传递.引用传递. 1.值传递 将已经初始化的变量值(或常量)传递到函数中. 例如: int func(int value) { int ret = value++; ...

最新文章

  1. MobileNets论文阅读笔记
  2. 启用第三方Chrome插件
  3. Eclipse旧版本Luna SR2(版本4.4.2)下载地址
  4. 2019.7.17刷题统计
  5. php中时间怎么自动实现的,php怎么实现服务器时间自动跳动
  6. Linux服务器上安装node.js
  7. python 函数重载_python中有函数重载吗
  8. 软件工程-软件小组的组织形式
  9. 03C++语言对C的增强——实用性、变量检测、struct类型、C++中所有变量和函数都必须有类型、bool类型、三目运算符...
  10. 算法导论第三版 第4章习题答案
  11. 在EnableQ创建一张问卷
  12. 黑苹果appstore下载软件报错,不能下载解决方法
  13. Cesium模型压平
  14. 将无线鼠标改造成有线鼠标
  15. UART BootROM
  16. C# FileInfo
  17. python的xlrd读取Excel数据失败: raise XLRDError(FILE_FORMAT_DESCRIPTIONS[file_format]+‘; not supported‘) ...
  18. Internet Information Services 5.0 技术概述(转)
  19. Misra-C编码规范全解读 - 前言
  20. 医院信息系统时要注意事项

热门文章

  1. Python如何将列表分成均匀大小的块?
  2. python超神之路:python异常对照表
  3. day2---while else
  4. dubbo-admin构建报错
  5. eclipse报错: Could not generate secret
  6. 详解Session分布式共享(.NET CORE版)
  7. PHP-CGI, FastCGI, PHP-FPM的关系和区别
  8. 【转】符串搜索工具及XenoCode字符串自动解密工具
  9. Node — 第二天
  10. 数据可视化(BI报表的开发)第三天