C++中引用概念

前段时间在学习C++,学习到了引用的概念,当时也查了好多的资料,网上也有很多关于引用的帖子,多是引用和指针的关系,谭浩强C++中对引用的介绍也不是很多,今天把它们整理出来,相信也会对大家有所帮助,关于C++中其它的一些概念我也会持续更新中,大家可以多多关注下我的博客!

 

 1、什么是引用?申明和使用引用要注意哪些问题?

答: 引用就是某个目标变量的 别名 ”(alias) ,对应用的操作与对变量直接操作效果完全相同。 申明一个引用的时候,切记要对其进行初始化 。引用声明完毕后,相当于目标变量名有两个名称,即该目标原名称和引用名, 不能再把该引用名作为其他变量名的别名 。声明一个引用,不是新定义了一个变量,它只表示该引用名是目标变量名的一个别名, 它本身不是一种数据类型 因此引用本身不占存储单元,系统也不给引用分配存储单元 不能建立数组的引用

2、将引用作为函数参数有哪些特点?

1 )传递引用给函数与传递指针的效果是一样的 。这时,被调函数的形参就成为原来主调函数中的实参变量或对象的一个别名来使用,所以在被调函数中对形参变量的操作就是对其相应的目标对象(在主调函数中)的操作。

2 )使用引用传递函数的参数,在内存中并没有产生实参的副本 它是直接对实参操作 ;而使用一般变量传递函数的参数,当发生函数调用时,需要给形参分配存储单元,形参变量是实参变量的副本; 如果传递的是对象,还将调用拷贝构造函数 。因此, 当参数传递的数据较大时,用引用比用一般变量传递参数的效率和所占空间都好。

3 )使用指针作为函数的参数虽然也能达到与使用引用的效果,但是,在被调函数中同样要给形参分配存储单元, 且需要重复使用 "* 指针变量名 " 的形式进行运算,这很容易产生错误且程序的阅读性较差;另一方面,在主调函数的调用点处,必须用变量的地址作为实参。 而引用更容易使用,更清晰。

3在什么时候需要使用常引用

如果既要利用引用提高程序的效率,又要保护传递给函数的数据不在函数中被改变,就应使用常引用。常引用声明方式: const 类型标识符  & 引用名 = 目标变量名;

1

int a ;
const int &ra=a;
ra=1; //
错误
a=1; //
正确

2

string foo( );
void bar(string & s);

那么下面的表达式将是非法的:

bar(foo( ));
bar("hello world");

原因在于 foo( ) "hello world" 串都会产生一个临时对象,而在 C++ 中,这些临时对象都是 const 类型的。因此上面的表达式就是试图将一个 const 类型的对象转换为非 const 类型,这是非法的。

引用型参数应该在能被定义为 const 的情况下,尽量定义为 const

4.引用作为函数返回值类型的格式、好处和需要遵守的规则?

格式:类型标识符  & 函数名(形参列表及类型说明) { // 函数体  }

好处:在内存中不产生被返回值的副本;(注意:正是因为这点原因,所以返回一个局部变量的引用是不可取的。因为随着该局部变量生存期的结束,相应的引用也会失效,产生 runtime error!

注意事项:

1 )不能返回局部变量的引用。这条可以参照 Effective C++[1] Item 31 。主要原因是局部变量会在函数返回后被销毁,因此被返回的引用就成为了 " 无所指 " 的引用,程序会进入未知状态。

2 )不能返回函数内部 new 分配的内存的引用。这条可以参照 Effective C++[1] Item 31 。虽然不存在局部变量的被动销毁问题,可对于这种情况(返回函数内部 new 分配内存的引用),又面临其它尴尬局面。例如,被函数返回的引用只是作为一个临时变量出现,而没有被赋予一个实际的变量,那么这个引用所指向的空间(由 new 分配)就无法释放,造成 memory leak

3 )可以返回类成员的引用,但最好是 const 。这条原则可以参照 Effective C++[1] Item 30 。主要原因是当对象的属性是与某种业务规则( business rule )相关联的时候,其赋值常常与某些其它属性或者对象的状态有关,因此有必要将赋值操作封装在一个业务规则当中。如果其它对象可以获得该属性的非常量引用(或指针),那么对该属性的单纯赋值就会破坏业务规则的完整性。

4 )流操作符重载返回值申明为 引用 的作用:

流操作符 << >> ,这两个操作符常常希望被连续使用,例如: cout << "hello" << endl;  因此这两个操作符的返回值应该是一个仍然支持这两个操作符的流引用。可选的其它方案包括:返回一个流对象和返回一个流对象指针。但是对于返回一个流对象,程序必须重新(拷贝)构造一个新的流对象,也就是说,连续的两个 << 操作符实际上是针对不同对象的!这无法让人接受。对于返回一个流指针则不能连续使用 << 操作符。因此,返回一个流对象引用是惟一选择。这个唯一选择很关键,它说明了引用的重要性以及无可替代性,也许这就是 C++ 语言中引入引用这个概念的原因吧。赋值操作符 = 。这个操作符象流操作符一样,是可以连续使用的,例如: x = j = 10; 或者 (x=10)=100; 赋值操作符的返回值必须是一个左值,以便可以被继续赋值。因此引用成了这个操作符的惟一返回值选择。

3

i nclude <iostream.h>
int &put(int n);
int vals[10];
int error=-1;
void main()
{
put(0)=10; //
put(0) 函数值作为左值,等价于 vals[0]=10;
put(9)=20; //
put(9) 函数值作为左值,等价于 vals[9]=20;
cout<<vals[0];
cout<<vals[9];
}
int &put(int n)
{
if (n>=0 && n<=9 ) return vals[n];
else { cout<<"subscript error"; return error; }
}

5 )在另外的一些操作符中,却千万不能返回引用: +-*/ 四则运算符。它们不能返回引用, Effective C++[1] Item23 详细的讨论了这个问题。主要原因是这四个操作符没有 side effect ,因此,它们必须构造一个对象作为返回值,可选的方案包括:返回一个对象、返回一个局部变量的引用,返回一个 new 分配的对象的引用、返回一个静态对象引用。根据前面提到的引用作为返回值的三个规则,第 2 3 两个方案都被否决了。静态对象的引用又因为 ((a+b) == (c+d)) 会永远为 true 而导致错误。所以可选的只剩下返回一个对象了。

5. “引用与多态的关系?

引用是除指针外另一个可以产生多态效果的手段。这意味着,一个基类的引用可以指向它的派生类实例。

4

Class A; Class B : Class A{...}; B b; A& ref = b;

6. “引用与指针的区别是什么?

指针通过某个指针变量指向一个对象后,对它所指向的变量间接操作。程序中使用指针,程序的可读性差;而引用本身就是目标变量的别名,对引用的操作就是对目标变量的操作。此外,就是上面提到的对函数传 ref pointer 的区别。

7.什么时候需要引用

流操作符 << >> 、赋值操作符 = 的返回值、拷贝构造函数的参数、赋值操作符 = 的参数、其它情况都推荐使用引用。

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

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

相关文章

php 版本排序,四种常见排序算法--PHP版本

1、冒泡排序法/*** 冒泡排序* des 对一组数据&#xff0c;比较相邻数据的大小&#xff0c;将值小数据在前面&#xff0c;值大的数据放在后面。*/$array [2,5,1,3,7,4];$result bubble_sort($array);print_r($result);function bubble_sort($array){$len count($array);for (…

C#内建接口:IEnumerable

这节讲一下接口IEnumerable。01什么是Enumerable在一些返回集合数据的接口中&#xff0c;我们经常能看到IEnumerable接口的身影。那什么是Enumerable呢&#xff1f;首先它跟C#中的enum关键字所表达的意思是不同的&#xff0c; 从翻译上来看&#xff1a;可枚举的&#xff0c;展开…

ubuntu,kali linux和windows三系统流水账——写给自己

我先说一下ubuntu和windows双系统安装的几种方法&#xff0c;最后总结kali linux的安装&#xff0c;想起什么写什么&#xff0c;所以有点乱。然后记录一下自己的使用过程中遇见的问题和解决的方法&#xff0c;还有我的个人建议。 我个人安装的是目前最新的ubuntu16.04LTS。wind…

一个富二代仅凭“1+1”就压制了全世界的数学家两个世纪......

全世界只有3.14 % 的人关注了爆炸吧知识在数学界&#xff0c;“11”是一个超级大难题&#xff0c;吸引了许多优秀的数学家去攻关打boss。但至今还未有人闯关成功。这位被众多数学家恨得牙痒痒的罪魁祸首就是——克里斯蒂安哥德巴赫。克里斯蒂安哥德巴赫1690年3月18日&#xff0…

用C语言实现数组反序

题目: 比如输入:数组是1,2,3,4,5 反序后的结果是:5,4,3,2,1 实现代码如下 #include <stdio.h> //用数组反序数组 void reserve1(int a[],int n){int m=(n+1)/2;int i=0;for(i;i<m;i++){int j=n-1-i;int temp=a[i];a[i]=a[j];a[j]=temp;} } //用指针进行反…

ordersta在php中是什么意思,[求助]ststa中的几个问题

<p> (1)hausman检验的结果如下——是什么意思呢</p><p>Test: Ho: difference in coefficients not systematic</p><p> chi2(4) (b-B)[(V_b-V_B)^(-1)](b-B)<br/> -16.36 chi2<0 &g…

java中错误的源文件,关于Java源文件结构规则,说法错误的是()A.版权信息必须在java文件的开头B.package语句在imports...

关于Java源文件结构规则&#xff0c;说法错误的是()A&#xff0e;版权信息必须在java文件的开头B&#xff0e;package语句在imports更多相关问题霍乱患者产生“米泔样”粪便由下列哪种致病因素直接引起普通话是以北京语音为标准音,所以北京话就是普通话。 (7.0分)在蜗杆传动中,…

switch类型模式

switch的模式中有一种叫类型模式&#xff0c;可以根据switch的类型来执行对应的case&#xff0c;这点在代码中用到的比较频繁&#xff0c;特别是在对应同类型对象的操作中。本例是把一组数据&#xff0c;转成一种格式&#xff0c;就是很简单的使用switch类型模式实现&#xff0…

Android框架之网络开发框架Volley

1. Volley简介 我们平时在开发Android应用的时候不可避免地都需要用到网络技术&#xff0c;而多数情况下应用程序都会使用HTTP协议来发送和接收网络数据。Android 系统中主要提供了两种方式来进行HTTP通信&#xff0c;HttpURLConnection和HttpClient&#xff0c;几乎在任何项目…

史上最会抄的数学家!把阿拉伯数字直接抄进自己的书里,连中国几千年前的名著都惨遭毒手.........

全世界只有3.14 % 的人关注了爆炸吧知识大家都喜欢《蒙娜丽莎的微笑》&#xff0c;但你知道她为什么好看吗&#xff1f;《蒙娜丽莎的微笑》没错&#xff0c;她符合黄金分割法0.618原则嘛&#xff01;但你知道这世界上还有一个数列版的黄金分割法的吗&#xff1f;这个数列就是斐…

求数组里面的最大值和最小值

题目&#xff1a; 求数组里面的最大值和最小值比如&#xff1a;数组 1&#xff0c;2&#xff0c;3&#xff0c;4&#xff0c;5最大值是5&#xff0c;最小值是1代码实现&#xff1a; #include <stdio.h> int max,min; void getMaxAndMin(int a[],int n){int *q;qa;maxmin*…

【ASP.NET开发】.NET三层架构简单解析

这篇文章本来应该很早就写出来的&#xff0c;但是一直苦于自己的精神能力有限&#xff0c;而且已经到了我们学校的考试周&#xff0c;所以时间上还是有点紧迫。关键的一点就是&#xff0c;找不到合理的思路来写&#xff0c;思路没有的话&#xff0c;就算是再好的素材&#xff0…

高级php平时的工作,【高级PHP开发工作内容|工作职责|高级PHP开发做什么】-看准网...

职位要求1.能非常熟练PHP开发和调试语言&#xff1b;并且在Python/Ruby/Perl语言上有更好经验&#xff1b;良好的编码风格习惯和测试习惯维持系统的质量&#xff1b;2.乐于维持和提高团队的专业水平&#xff0c;甚至正面影响其他开发队伍&#xff1b;3.乐于了解业务需求、协助团…

C和C++里面常见错误和异常出现怎么解决总结(不断更新)

1、cannot open Debug/first.exe for writing 如下图: 原因:控制台没有关闭,不能写,因为编译的exe文件正在运行,而再次编译是要修改这个exe文件的,因为不让写,所以就抱着这个错。 解决办法:是看有没有运行编译后文件,如果正运行着,就将其关掉。 2、cannot conver…

PHP PDO

PDO:数据访问抽象层方法一 <?php //造dsn&#xff0c;驱动名&#xff1a;dbname数据库名&#xff1b;host服务器地址 $dsn"mysql:dbnamemydb;hostlocalhost"; //造pdo对象 $pdonew PDO($dsn,"root","135395"); //写sql语句 $sql"select…

有关[Http持久连接]的一切,卷给你看

上文中我的结论是&#xff1a; HTTP Keep-Alive 是在应用层对TCP连接进行滑动续约复用&#xff0c; 如果客户端/服务器稳定续约&#xff0c;就成了名副其实的长连接。目前所有的Http网络库都默认开启了HTTP Keep-Alive&#xff0c;今天我们从底层TCP连接和排障角度撕碎HTTP持久…

他从小把数学书当小说看,凭借一本书将全世界狠狠甩在身后,被誉为中国的牛顿...

全世界只有3.14 % 的人关注了爆炸吧知识你知道吗&#xff1f;我国也有牛顿哦。他就是魏晋时期的数学家——刘徽&#xff0c;人称“中国数学史上的牛顿”。刘徽沉迷学习公元225年&#xff0c;刘徽出生在山东滨州邹平市的一所农家小院里。从小&#xff0c;刘徽就表现得与别的孩子…

简单调试 Bash 脚本

用 Bash 写的脚本也可以进行调试&#xff0c;和 Python&#xff0c;Perl 等解释型语言一样。新建一个名为 servinfo 的脚本并增加可执行权限&#xff1a; $ vi servinfo#!/bin/bashecho "Hostname: $(hostname)" echo "Date: $(date)" echo "Kernel: …

PHP优于Node.js的五大理由

PHP是一款服务器端的脚本语言&#xff0c;主要用于动态网页开发&#xff0c;是目前最流行的开发语言之一。Node是一款用来编写高性能网络服务器的JavaScript工具包。文中将两者进行对比&#xff0c;列举了PHP优于Node.js的五大理由。一起来看下。 PHP优于Node.js的理由 容易托管…

C和C++语言编程里面常用函数或者编程技巧总结(不断更新)

1、我们输入字符串输出字符串可以这样 char a[20];gets(a);puts(a);puts("hello word"); 2、输出字符串putchar()、printf("%p\n",p);cout<<p; #include<stdio.h> void main(){char a[20]={"chenyu1"};char *c="chenyu2"…