C++中函数返回引用

2023-11-13

1. 返回引用和不返回引用的区别

下面两个代码是在类中的成员函数,而m_data_变量为类的私有成员变量。

int& at()
{
    return m_data_;
}
int at()
{
    return m_data_;
}

上面两个函数,第一个返回值是int的引用int&,第二个返回值是int,但是二者有什么区别?

  1. 返回值为引用型(int& )的时候,返回的是地址,因为这里用的是 int& a=A.at(); ,所以a和m_data_指的是同一块地址。
  2. 返回值不是引用型(int)的时候,返回的是一个数值。这个时候就很有意思了,编译器是先将这个数值放入一个内存中,再把这个地址付给a,此时的a代表的地址和m_data_代表的地址不一样。
  3. 综上两点可以看出,当返回的值是引用型时,会返回该变量的地址。当返回的值不是引用型时,编译器会专门给返回值分配出一块内存的
int& at()
{
    return m_data_;
}

int a=at();

上面代码的执行过程为:

  1. 函数返回类对象中的成员变量m_data的地址。(这里会不会造成私有变量的泄露?)
注意:
函数返回引用,要慎重,一定要保证函数结束后,返回的引用是有效的

2. 返回引用的优点

一般用作类对象的返回值,可以减少临时对象的申请、构造等操作,节省空间时间,比如

String &operator=(const String &)
{
//若干代码
return *this;//返回自身引用
}

3. 函数返回若不返回一个变量的引用,则一定会生成一个临时变量

看下面的函数,返回的是t而不是&t,所以一定会有临时变量产生。

T function1(){
    T t(0);
    return t;
}
T x=function1();

这里的过程是:

  1. 创建命名对象t
  2. 拷贝构造一个无名的临时对象,并返回这个临时对象
  3. 由临时对象拷贝构造对象x
  4. T x=function1();这句语句结束时,析构临时对象
    这里一共生成了3个对象,一个命名对象t,一个临时对象作为返回值,一个命名对象x。

下面的函数稍微复杂一定,它没有先定义一个中间变量t,看起来似乎是直接返回了一个临时变量。但实际上,如果不经过c++的优化,那么它并没有提高效率,因为它还是创建了3个对象。

T function2(){
     return T(0);
}
T x=function2();

这里的过程是:

  1. 创建一个无名对象
  2. 由无名对象拷贝构造一个无名的临时对象
  3. 析构无名对象,返回临时对象
  4. 由临时对象拷贝构造对象x
  5. T x=function2()语句结束时,析构临时对象。

这里一共生成了3个对象,其中有2个对象都是马上被析构掉的,不能被后面的代码使用。既然是这样,那么就会有优化的余地,可以尝试着不要前面的两个临时变量。c++确实会做这样的优化,优化后的c++会避免匿名对象和临时对象这两个对象的生成,而直接生成x,这样就减少了两次对象生成-回收的消耗,提高了程序性能。

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

C++中函数返回引用 的相关文章

  • 如何从 C# 中的 dataTable.Select( ) 查询中删除单引号?

    所以我有一个经销商名称列表 我正在我的数据表中搜索它们 问题是 一些傻瓜必须被命名为 Young s 这会导致错误 drs dtDealers Select DealerName dealerName 所以我尝试替换字符串 尽管它对我不起作
  • 如何在多线程C++ 17程序中交换两个指针?

    我有两个指针 pA 和 pB 它们指向两个大的哈希映射对象 当pB指向的哈希图完全更新后 我想交换pB和pA 在C 17中 如何快速且线程安全地交换它们 原子 我是 c 17 的新手 2个指针的原子无等待交换可以通过以下方式实现 inclu
  • 如何捕获未发送到 stdout 的命令行文本?

    我在项目中使用 LAME 命令行 mp3 编码器 我希望能够看到某人正在使用什么版本 如果我只执行 LAME exe 而不带参数 我会得到 例如 C LAME gt LAME exe LAME 32 bits version 3 98 2
  • 为什么pow函数比简单运算慢?

    从我的一个朋友那里 我听说 pow 函数比简单地将底数乘以它的指数的等价函数要慢 例如 据他介绍 include
  • IdentityServer 4 对它的工作原理感到困惑

    我阅读和观看了很多有关 Identity Server 4 的内容 但我仍然对它有点困惑 因为似乎有很多移动部件 我现在明白这是一个单独的项目 它处理用户身份验证 我仍然不明白的是用户如何注册它 谁存储用户名 密码 我打算进行此设置 Rea
  • 为什么在 WebApi 上下文中在 using 块中使用 HttpClient 是错误的?

    那么 问题是为什么在 using 块中使用 HttpClient 是错误的 但在 WebApi 上下文中呢 我一直在读这篇文章不要阻止异步代码 https blog stephencleary com 2012 07 dont block
  • Visual Studio 在构建后显示假错误

    我使用的是 Visual Studio 2017 构建后 sln在调试模式下 我收到错误 但是 当我通过双击错误列表选项卡中的错误来访问错误时 错误会从页面中消失 并且错误数量也会减少 我不太确定这种行为以及为什么会发生这种情况 有超过 2
  • 从客户端访问 DomainService 中的自定义对象

    我正在使用域服务从 Silverlight 客户端的数据库中获取数据 在DomainService1 cs中 我添加了以下内容 EnableClientAccess public class Product public int produ
  • unordered_map 中字符串的 C++ 哈希函数

    看起来 C 标准库中没有字符串的哈希函数 这是真的 在任何 c 编译器上使用字符串作为 unordered map 中的键的工作示例是什么 C STL提供模板专业化 http en cppreference com w cpp string
  • 识别 Visual Studio 中的重载运算符 (c++)

    有没有办法使用 Visual Studio 快速直观地识别 C 中的重载运算符 在我看来 C 中的一大问题是不知道您正在使用的运算符是否已重载 Visual Studio 或某些第三方工具中是否有某些功能可以自动突出显示重载运算符或对重载运
  • 在视口中查找 WPF 控件

    Updated 这可能是一个简单或复杂的问题 但在 wpf 中 我有一个列表框 我用一个填充数据模板从列表中 有没有办法找出特定的数据模板项位于视口中 即我已滚动到其位置并且可以查看 目前我连接到了 listbox ScrollChange
  • 在 NaN 情况下 to_string() 可以返回什么

    我使用 VS 2012 遇到了非常令人恼火的行为 有时我的浮点数是 NaN auto dbgHelp std to string myFloat dbgHelp最终包含5008角色 你不能发明这个东西 其中大部分为0 最终结果是 0 INF
  • 如何在 C 中安全地声明 16 位字符串文字?

    我知道已经有一个标准方法 前缀为L wchar t test literal L Test 问题是wchar t不保证是16位 但是对于我的项目 我需要16位wchar t 我还想避免通过的要求 fshort wchar 那么 C 不是 C
  • 使 Guid 属性成为线程安全的

    我的一个类有一个 Guid 类型的属性 该属性可以由多个线程同时读写 我的印象是对 Guid 的读取和写入不是原子的 因此我应该锁定它们 我选择这样做 public Guid TestKey get lock testKeyLock ret
  • C++ new * char 不为空

    我有一个问题 我在 ASIO 中开发服务器 数据包采用尖头字符 当我创建新字符时 例如char buffer new char 128 我必须手动将其清理为空 By for int i 0 i lt 128 i buffer i 0x00
  • OpenGL:仅获取模板缓冲区而没有深度缓冲区?

    我想获取一个模板缓冲区 但如果可能的话 不要承受附加深度缓冲区的开销 因为我不会使用它 我发现的大多数资源表明 虽然模板缓冲区是可选的 例如 排除它以利于获得更高的深度缓冲区精度 但我还没有看到任何请求并成功获取仅 8 位模板缓冲区的代码
  • 在 Windows Phone silverlight 8.1 上接收 WNS 推送通知

    我有 Windows Phone 8 1 silverlight 应用程序 我想使用新框架 WNS 接收通知 我在 package appxmanifest 中有
  • 堆栈是向上增长还是向下增长?

    我在 C 中有这段代码 int q 10 int s 5 int a 3 printf Address of a d n int a printf Address of a 1 d n int a 1 printf Address of a
  • 使用 C 在 OS X 中获取其他进程的 argv

    我想获得其他进程的argv 例如ps 我使用的是在 Intel 或 PowerPC 上运行的 Mac OS X 10 4 11 首先 我阅读了 ps 和 man kvm 的代码 然后编写了一些 C 代码 include
  • 如何将十六进制字符串转换为无符号长整型?

    我有以下十六进制值 CString str str T FFF000 如何将其转换为unsigned long 您可以使用strtol作用于常规 C 字符串的函数 它使用指定的基数将字符串转换为 long long l strtol str

随机推荐

  • 错误ERROR: cannot launch node of type

    ERROR cannot launch node of type robot vision motion detector py can t locate node motion detector py in package robot v
  • javaweb之MVC购物车(加入购物车,订单,订单详情)

    MVC Model View Controller 是软件工程中的一种软件架构模式 它把软件系统分为模型 视图和控制器三个基本部分 用一种业务逻辑 数据 界面显示分离的方法组织代码 将业务逻辑聚集到一个部件里面 在改进和个性化定制界面及用户
  • Scala学习路线

    本文是类比Java基础知识的 Scala学习笔记 1 Scala基础 1 Scala一些基础知识 https blog csdn net hzp666 article details 114842022 2 控制结构 if判断 https
  • 自然人税收管理系统服务器,【轻松学个税申报】自然人税收管理系统客户端操作...

    2018年8月1日个人所得税代扣代缴申报软件 自然人税收管理系统客户端正式上线 新的软件在界面 操作方法 实现功能等较多变化 为了大家能够熟练操作与应用 从今天起开始为大家带来自然人税收管理系统客户端操作应用 今天我们先来说一说新建帐户 一
  • 小学生Python编程 —— 欢乐钢琴

    孩子的又一作品 欢乐钢琴 from pgzrun import WIDTH 960 HEIGHT 720 o 0 name s song Actor name str o png 480 180 a press False 动效函数 def
  • sublime text3下搭建Python IDE--Anaconda插件(自动补全)

    今天自己想在sublime text3下装个python自动补全插件 当安装一个包管理器时 Package Contral 时 ctrl shift p输入Install Package时 总是报错说没有这个包 在网上也找了很多解决办法 有
  • Android Apache安装及局域网手机无法访问解决办法

    Android Apache安装及局域网手机无法访问解决办法 Apache是一款常用的开源Web服务器软件 可以在Android设备上安装并提供Web服务 本文将介绍如何在Android设备上安装Apache 并提供解决方案以解决在同一局域
  • 代码静态分析工具——splint的学习与使用

    引言 最近在项目中使用了静态程序分析工具PC Lint 体会到它在项目实施中带给开发人员的方便 PC Lint是一款针对C C 语言 windows平台的静态分析工具 FlexeLint是针对其他平台的PC Lint版本 由于PC Lint
  • ResNet简介

    ResNet Residual Network 此网络于2015年 国人何先生提出 用于解决随着深度学习的层数加深造成的网络退化现象和梯度消失 梯度爆炸 问题1 退化现象 当深度学习的各项指标能够随着训练轮数收敛的情况下 网络的层数增强未能
  • 深度学习车辆检测实现自动驾驶

    在本文中 我将通过一个车辆检测示例演示如何使用深度学习创建目标检测器 相同的步骤可用于创建任何目标探测器 我经常有朋友和同事问我自动驾驶系统如何感知周围的环境并做出 人类 的决定 目标检测是指对图像和视频中的目标进行定位和分类 下图显示了一
  • MySQL体系结构及数据库在Linux的部署

    数据库 存储数据的仓库 是长期存放在计算机内 有组织 可共享的大量数据的集合 数据库中的数 据按照一定数据模型组织 描述和存储 具有较小的冗余度 较高的独立性和易扩展性 并为各种用户共享 先来看看MySQL的体系架构图 可以看出MySQL的
  • 关于串口通信协议的解析,该怎么解决

    关于串口通信协议的解析 该怎么解决 串口通信协议 由于本系统采用非规范式输入 导致一帧数据可能分成几次接收 为了能够判断一帧数据是否接收完整 本系统制定了一套特殊的串口通信协议 如附图所示 附图 通信协议定义 在本系统的串口通信协议中 一帧
  • sql sever2008 R2 检测到索引可能已损坏。请运行 DBCC CHECKDB。

    1 设置成单用户状态 USE MASTER ALTER DATABASE DBNAME SET SINGLE USER GO DBNAME为修复的数据库名 2 执行修复语句 检查和修复数据库及索引 dbcc checkdb DBNAME R
  • 【pip】彻底解决 module ‘tensorflow‘ has no attribute ‘random_normal‘

    翻译 tensorflow显示没有random normal模块 解决 将代码中的 tf random normal 用tf random normal代替 区分 与
  • [leetcode]python3 算法攻略-回文链表

    请判断一个链表是否为回文链表 方案一 指针法 class Solution def isPalindrome self head 判断一个链表是否是回文的 很自然的想法就是两个指针 一个指针从前往后走 一个指针从后往前走 判断元素值是否相同
  • mysql读写分离与监控的使用(proxysql)

    os rhel 7 3 mysql 5 7 proxysql 1 4 15 1 ip 规划如下 172 25 11 1 node1 proxysql 172 25 11 2 node2 mysql master 172 25 11 3 no
  • 对于解决Visual Studio中scanf函数报错的原因及解决方法

    对于C语言初学者 可能会用到devC 或者是visual studio软件 我本人是比较推荐visual studio软件的 毕竟这个软件使用起来功能比devc 软件功能更多 而初学者在使用visual studio软件时会发现在使用初始的
  • Unity-委托2种常用使用场景总结

    委托使用场景1 调用委托 可以分发多个方法出去 举例 定义多个通知不同人的信息 例如经理 员工 客户 可以针对性的制定不同的通知 调用委托 可以一次性的群发给他们 委托使用场景2 方法的参数是个方法 例如按钮方法 参数是一个点击事件的方法
  • 麦克灵敏度调整

    1 先看MIC电路连接 这是个差分输入的例子 MICP2和MICN2是一对差分信号 经过C156的滤波 输入到MIC两端 MIC两引脚分别是到地和供电 上图的R177参数就关系到MIC输入的灵敏度 2 电阻R177影响灵敏度分析 MICBI
  • C++中函数返回引用

    1 返回引用和不返回引用的区别 下面两个代码是在类中的成员函数 而m data 变量为类的私有成员变量 int at return m data int at return m data 上面两个函数 第一个返回值是int的引用int 第二