c++_函数返回值,引用&作为函数返回值

2023-11-16

函数返回值

返回值是[const] T &

ST operator*( ST & a, ST & b){
	return ST( a.data * b.data);
}
ST a, b;

当你实际使用时: ST ret = a * b;
一共会有2次的 构造函数: 一次是ret 一次是函数返回值的temp临时对象

我们知道, 这个temp临时对象, 肯定是徒劳的, 是否可以优化 把它去掉呢???


错误做法1

ST & operator*( ST & a, ST & b){
	return ST( a.data * b.data);
}

返回一个: 指向临时对象的(引用/指针), 这自然是错误的; 因为临时对象,马上释放, 引用已经释放的内存 报错

错误做法2

ST & operator*( ST & a, ST & b){
	return *( new ST( a.data * b.data));
}

当遇到a * b * a时, 此时, a * b这个对象 用户就没有得到他, 他是匿名对象, 自然也就无法释放了. 造成: 内存泄漏

错误做法3

ST & operator*( ST & a, ST & b){
	static ST ret( a.data * b.data);
	return ret;
}

当遇到: if( a * b == c * d)时, 返回值永远是true.
因为, 所有operator函数的调用, 返回值都是同一个对象ret!!!
ret的值, 为, 最后一次 调用 operator
函数的 值.
所以, if( a * b == c * d), 其实他的本质是: if( c * d == c * d) 错误


所以, 请永远不要: 试图通过返回const T & 来 减少临时对象 优化程序

返回ST &, 只有1个场景:

class ST{
	Obj data;

	Obj & get_data(){ return data;}   ' 即, 返回的这个对象, 在该函数调用前 (已经)存在了!!! '
};

如果, 就是要优化 减少临时对象, 只有1种做法:

void func_multiply( ST & a, ST & b, ST & ret){
	ret.data = a.data * b.data;
}
ST a, b;

当你调用时: ST ret; func_multiply( a, b, ret);

返回值的类型是 T

返回值是T的意思是: 返回值是T, 不是T * T &

返回的对象是 局部对象

ST Get(){
	ST ret;
	return ret;
}

当你调用Get();时, 总共只会产生1个对象即ret
即: 函数返回给外部的对象, 就是这个ret对象本身

即, 你ST t = Get(); 时, 右侧的这个Get()所代表的对象 就是ret本身

这里好像很难理解, 因为此时的ST t = Get();, 右侧的ret对象 已经超出了 他的作用域!!!
你应该这样理解: return语句, 并不是一个函数的结束, 函数的结束 是取决于: 函数的右括号}

ST Get(){
	ST ret;
	return ret;
}

ST t = Get(), func1(), func2();

首先一点是肯定的: 接收到ret的析构函数, 就意味着: Get函数的结束

执行流程是:

  • 进入Get函数, 到return这行语句时, 将ret这个对象 本身, 返回给ST t这个对象 注意, 此时Get函数, 并没有结束!!!
    即, return就像是: 发送了一个信号, 这个信号 带着ret对象本身 返回到 原先切入点, 同时, 将ret这个对象 "标记"为: 临时对象
  • 然后, 紧接着 ,执行 func1, func2, 直到执行到;结束
  • 重点: 此时, 会返回到Get函数里, 然后遇到}, 这个ret才会 delete掉

即, return语句, 就像是Qt里的 [信号与槽], 他会跳到别的地方执行, 执行完后, 还会回来的!!!


Foo Get(){
	Foo a;
	return a;	' 或 return Foo(); 一样的 '
};

当你外界 Foo b = Get();, 全程只有1个对象a产生!!! (只有1个析构函数, 1个无参构造函数)

首先, 这确实是非常的 不可思议!!! (但是, 逻辑来讲, 这非常的合理!!)
因为, 你的目的, 就是让 a 和 b 两个对象 是相同的; 而, 如果 能用1个对象完成, 那肯定比用2个对象完成, 要好的多

一定要牢记这个知识点!!!

ST Get(){ ST o; return o;}
vector< ST> Get(){ vector< ST> o; return 0;}

' 一定要写成: '
ST ret = Get();   ' &ret == &o '
vector< ST> ret = Get(); ' &ret[0,1,2,..] == &o[0,1,2,..] '
	' 这里的这个=等号, 不会引发任何的 对象构造复制 '

-------

' 千万不要写成: '
ST ret; 	ret = Get();
vector< ST> ret;	ret = Get();
	' 天壤差别,   造成 (对象复制) '

实现原理

暂时还不知道…
我猜可能是: 你虽然是写成ST a = Get(); vector< ST> b = Get();
但是, 其实他是会变成: ST && a = Get(); vector< ST> && b = Get();


返回的对象是 全局对象

ST g;

ST Get(){
	return g;
}

这种写法, 和 把 ST g, 放到Get函数里, 是天壤之别的!!!

程序一开始, g的构造; 然后执行: Get();return g时, 返回的 并不是g!!!
而是会调用一次ST的构造, 即构造一个新的临时对象, 给返回回去.


反问, 如果说, 返回的就是g本身. 那么&Get()是可以的, 而且Get().set_xxx()会修改 全局变量g的值.
这个功能, 应该是: ST & Get(); 而此时是: ST Get(); 这并不符合ST Get()函数的 定义.

所以, 当ST Get(){ return obj;} 返回的obj, 是一个全局对象时, 他会构造一个临时对象 给返回


再比如说:

class Bar{
	Foo foo;
	Foo get_foo(){ return foo;}
};

当你调用 bar.get_foo();时, 返回的, 并不是bar.foo本身, 而是会构造一个(临时对象)拷贝构造, 返回回去

总之: Foo get(){ return ret;} 不管这个函数, 是全局/member函数
对于这个get(){} 函数作用域来说

  • 如果这个ret, 是这个get作用域里的, 即, ret离开get作用域 就消失, 那么: 返回值的 就是这个ret本身!!!
  • 否则, 这个ret, 离开get作用域后 依然存在, 那么, 在返回时: 不会返回ret本身, 而是会 构造一个(临时对象) 返回出去!!!

实例

ST Get(){ return ST();}

ST Gett(){ return Get();}

ST Gettt(){ return Gett();}

调用Gettt();时, 只会调用1次 ST的构造 (对应上面ST();)!!!
因为: 当 返回值是: 局部变量 时, 返回的就是这个对象本身.


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c++_函数返回值,引用&作为函数返回值 的相关文章

随机推荐

  • 金山WPS暑期实习招聘笔试题2013-7-28

    C 试卷B卷 应聘职位1 2 姓 名 性 别 学 位 所在院校 所学专业 联系电话 电子邮件 毕业时间 获知招聘信息渠道 说明 答题时间为 100 分钟 自我判断题 请选择最符合您本人意愿的一项 1 你
  • 从项目实施层面解析STEAM教育

    转自 https baijiahao baidu com s id 1614434815561381532 wfr spider for pc 一 引言 近几年大家常常听到STEAM教育这个词 似乎一夜之间所有的培训机构的课程都变成了STE
  • 第9章_瑞萨MCU零基础入门系列教程之SCI I2C

    本教程基于韦东山百问网出的 DShanMCU RA6M5开发板 进行编写 需要的同学可以在这里获取 https item taobao com item htm id 728461040949 配套资料获取 https renesas do
  • Android-SharedPreferences实现记住密码和自动登录

    效果图 第一次进入进来 勾选记住密码和自动登录成功后 第二次进来 说明 中间存在的图片或者多余的其他部分可删掉 留下最主要的填写部分和登陆按钮即可 功能还是可以实现的 XML文件
  • QQ飞车手游设计分析

    腾讯系竞速手游的逆袭 QQ飞车手游设计分析 前言 这是中山大学数据科学与计算机学院软件工程2019年3D游戏编程与设计的作业1 导语 在中国巨大的游戏市场下 手游战场上的战火从未熄灭 其中以王者荣耀为首的MOBA类手游与以PUBG 现改名和
  • 【Flink Rest-ful API 】

    Flink 有了一些查询job状态指标的API 这些监控 API is a REST ful API 接受 HTTP 请求并返回JSON data 这些监控API以jobManager中web server 为基础 默认其监听端口为8081
  • PHPstudy安装教程

    首先简单介绍一下PHPStudy PHPStudy是一个Windows下的Apache Nginx php MYSQL的集成开发环境 PHPStudy比较适合快速的在windows下部署一个Web开发环境 而且便于安装 部署方便 服务器本身
  • linux环境下安装nginx

    一 准备安装环境 安装nginx需要系统相关插件 所以在安装前先检查哈是否有这些插件 如果没有 则要先安装这些插件 由于笔者是新的虚拟机环境 所以这些插件都没有 都需要安装 读者可以根据自己实际情况进行相关操作 1 安装 gcc gcc c
  • HTML引用公共组件

    在test html引用footer html 效果图 代码 test html div 我是頁面 div div class footer div
  • 《再也不怕elasticsearch》REST API调用

    REST API调用 大家好我是迷途 一个在互联网行业 摸爬滚打的学子 热爱学习 热爱代码 热爱技术 热爱互联网的一切 再也不怕elasticsearch系列 帅途会慢慢由浅入深 为大家剖析一遍 各位大佬请放心 虽然这个系列帅途有时候更新的
  • linux桌面小程序开发日记2(pyqt5+yolov5)

    linux桌面小程序开发日记2 使用Pyqt5 制作一个界面 并连接摄像头 最后一篇博客地址 https blog csdn net Liuchengzhizhi article details 123692365 B站视频 https w
  • VS Code Material Icon Theme插件设置自定义文件夹图标关联

    VS Code Material Icon Theme插件设置自定义文件夹图标关联 方法与分析 自定义文件夹图片命名和位置如下 vscode extensions pkief material icon theme 4 5 0 icons
  • 程序的基本结构

    程序的基本结构 1 顺序结构 2 选择结构 选择结构如下图所示 当条件成立时 执行模块A否则执行模块B 3 循环结构 循环结构又两种形式当型循环和直道型循环 当型循环 先判断条件 条件成立就反复执行程序模块 当条件不成立时结束循环 当型循环
  • Django视图类View源码分析

    Django视图类View源码分析 一 视图函数 django中的视图函数 就是视图功能由函数实现 响应 或渲染模板后返回HTML 或直接返回JSON数据 参数 视图函数的第一个参数必须是request对象 文本响应 from django
  • 纯干货:接口自动化测试的思考和技术实现

    一 思考 什么是自动化测试 自动化测试是把人为驱动转换成计算机驱的测试行为 人对于接口的测试行为 第一步 理解业务需求 一般来说可以从需求理解接口的行为和描述 行为 当什么情况 做什么操作 发生什么事情 描述 情况是什么 操作是什么等 第二
  • Rust- 类型系统

    The type system in Rust is one of its core features supporting a range of different types and providing a powerful syste
  • 为什么String要被设置为不可变类?百日百题(2/100)

    问题引入 我们学习了String的数据类型 知道了String类型一旦生成就不会再发生改变 这就是他的不可变性 也就意味着每次修改都会产生一个新的String变量 对性能影响较大 StringBuilder和StringBuffer产生的对
  • [Hyperf]源码阅读:验证器验证规则

    hyperf validation src Concerns ValidatesAttributes php
  • 单向链表的Java实现,以及相关函数。

    如上图所示就是单向链表的示意图 下面就是Java实现单向链表的基本过程与源码 可以跑起来的 1 创建一个节点类 package com wpl snglelink public class Node public Object getDat
  • c++_函数返回值,引用&作为函数返回值

    catalog 函数返回值 返回值是 const T 返回值的类型是 T 返回的对象是 局部对象 实现原理 返回的对象是 全局对象 实例 函数返回值 返回值是 const T ST operator ST a ST b return ST