当前位置: 首页 > news >正文

函数返回值:引用类型和非引用类型

        引用的概念是C++中的,C中不存在引用。


问题1:返回引用类型和非引用类型的区别。

        返回非引用类型:函数的返回值用于初始化在调用函数时创建的临时对象。用函数返回值初始化临时对象与用实参初始化形参的方法是一样 的。如果返回类型不是引用,在调用函数的地方会将函数返回值复制给临时对象。且其返回值既可以是局部对象,也可以是求解表达式的结果。

        返回引用类型:当函数返回引用类型时,没有复制返回值。相反,返回的是对象本身。所以,其效率更高。


问题2:什么时候返回引用是正确的?而什么时候返回const引用是正确的? 

        返回指向函数调用前就已经存在的对象的引用是正确的。当不希望返回的对象被修改时,返回const引用是正确的。


问题3:什么情况下返回引用才是正确的?*********************请直接忽略问题3,这次回来看后,发现观点欠论据*********************

        返回引用,要求在函数的参数中,包含有以引用方式或指针方式存在的,需要被返回的参数。比如:

	int& abc(int a, int b, int c, int& result){

 	result = a + b + c;
  	 return result;
}
        或者:

int& abc(int a, int b, int c, int *result){
  *result = a + b + c;
   return *result;
}
       这种形式是错误的:(设计思想错误,can compile and run)
int& abc(int a, int b, int c){
   return a + b + c;
}

注意4:

  • 返回的引用类型是左值。
  • 千万不要返回局部对象的引用!千万不要返回指向局部对象的指针!函数执行完毕时,将释放分配给局部对象的存储空间。此时对局部对象的引用就会指向不确定的内存!返回指向局部对象的指针也是一样的,当函数结束时,局部对象被释放,返回的指针就变成了不再存在的对象的悬垂指针。


关于临时对象5:返回非引用类型,存在临时对象这个概念。

  • 函数的返回值用于初始化在调用函数时创建的临时对象(temporary object),如果返回类型不是引用,在调用函数的地方会将函数返回值复制给临时对象。
  • 在求解表达式的时候,如果需要一个地方存储其运算结果,编译器会创建一个没命名的对象,这就是临时对象。C++程序员通常用temporary这个术语来代替temporary object。用函数返回值初始化临时对象与用实参初始化形参的方法是一样的。
  • 当函数返回非引用类型时,其返回值既可以是局部对象,也可以是求解表达式的结果。


题外话6:

      main函数允许没有返回值就可结束,编译器会自动为其默认返回0。将主函数main返回的值视为状态指示器,返回0表示程序运行成功,其他大部分返回值则表示失败。


代码分析7:(注意看注释)

#include <iostream>
using namespace std;
int val()
{
    int i = 1 ;
    return i ;
}
int& ref()
{
   int j = 3 ;
   int &i = j ;  // comment it will also compile.
   return j ;  // 不能返回局部对象的引用,可以将int j = 3 ;放在全局作用域。
               // 但是编译器不会报错,只是设计思想有问题,请注意main函数中Attention 1和Attention 2的结果。
}

int main()
{
    int  vv = val();
    //Sconst int& rv = val();  // 编译器报错,error: invalid initialization of non-const reference of type 'int&' from an rvalue of type 'int'
                      // const int& rv = val(); can compile
    int  vr = ref() ;  // Attention 1,编译器不会报错。
    int& rr = ref() ;  // Attention 2
    cout << vv << endl ;
    //cout << rv << endl ;
    cout << vr << endl ;
    cout << rr << endl ;
    return 0;
}
运行结果1:


运行结果2:




参考博文:http://blog.csdn.net/keyouan2008/article/details/5741917

                    http://chinaxxren.iteye.com/blog/1547449

相关博文:关于C++引用的分析


相关文章:

  • C语言表达式和表达式的值
  • C语言知识点考题
  • 判断一个数是否为2的幂次
  • C99标准的新特性
  • C/C++标准资料
  • 如果我再次被面试,我会问的几个问题
  • Linux 常用命令记录
  • C++关键字
  • Open Broadcaster Software源码阅读笔记
  • 简单算法--迭代/递归
  • 背包九讲笔记
  • 关于类成员函数中静态变量的一点提示
  • C++ 强制类型转换若干问题
  • 面向对象设计原则
  • C++之父FAQ阅读笔记
  • 【comparator, comparable】小总结
  • Eureka 2.0 开源流产,真的对你影响很大吗?
  • JS+CSS实现数字滚动
  • RedisSerializer之JdkSerializationRedisSerializer分析
  • Redis字符串类型内部编码剖析
  • vue-router的history模式发布配置
  • 关于extract.autodesk.io的一些说明
  • 跨域
  • 为物联网而生:高性能时间序列数据库HiTSDB商业化首发!
  • Spring第一个helloWorld
  • 阿里云移动端播放器高级功能介绍
  • 组复制官方翻译九、Group Replication Technical Details
  • (ZT)出版业改革:该死的死,该生的生
  • (超详细)语音信号处理之特征提取
  • (翻译)terry crowley: 写给程序员
  • (附源码)小程序儿童艺术培训机构教育管理小程序 毕业设计 201740
  • (心得)获取一个数二进制序列中所有的偶数位和奇数位, 分别输出二进制序列。
  • (续)使用Django搭建一个完整的项目(Centos7+Nginx)
  • (转)Scala的“=”符号简介
  • (转)利用PHP的debug_backtrace函数,实现PHP文件权限管理、动态加载 【反射】...
  • .\OBJ\test1.axf: Error: L6230W: Ignoring --entry command. Cannot find argumen 'Reset_Handler'
  • .net core 6 使用注解自动注入实例,无需构造注入 autowrite4net
  • .NET 使用 ILMerge 合并多个程序集,避免引入额外的依赖
  • .NET/C# 使用 SpanT 为字符串处理提升性能
  • @TableId注解详细介绍 mybaits 实体类主键注解
  • [ vulhub漏洞复现篇 ] GhostScript 沙箱绕过(任意命令执行)漏洞CVE-2019-6116
  • [Big Data - Kafka] kafka学习笔记:知识点整理
  • [BZOJ3211]:花神游历各国(小清新线段树)
  • [CCIE历程]CCIE # 20604
  • [ESP32 IDF]web server
  • [flume$2]记录一个写自定义Flume拦截器遇到的错误
  • [HITCON 2017]SSRFme perl语言的 GET open file 造成rce
  • [INSTALL_FAILED_TEST_ONLY],Android开发出现应用未安装
  • [Java] 什么是IoC?什么是DI?它们的区别是什么?
  • [LeetCode] 178. 分数排名
  • [LeetCode] 2.两数相加
  • [linux] shell中的()和{}
  • [MAUI]集成高德地图组件至.NET MAUI Blazor项目
  • [NOI2014]购票
  • [office] excel2003进行可视性加密的方法 #媒体#其他#知识分享