您好,欢迎访问三七文档
C++中的引用PPT制作:武坤秀演讲:汪婷婷资料搜索:余金英杨倩位钰莹赵艳萍汪婷婷•引用的定义•引用是c++对c的一个重要扩充。在c++中,变量的引用就是变量的别用,因此引用又称为别名。•申明一个引用的格式•类型&引用名=已定义的变量名•(其中“&”是引用声明符,此时它不代表地址)•例如:int&j=i;(不是将变量i的值赋给引用j,而是使j成为变量i的引用,即变量i的别名)•注意:•1.引用不是一种独立的数据类型,它必须与某一种类型的变量相联系。在声明引用时,必须立即对它进行初始化,不能声明完成后在赋•inti=10;int&j;没有指定j代表哪个变量j=i;不能声明完成后再赋值•doublea;int&b=a;声明b是一个整型变量的别名,而a不是整型变量•(2)引用声明完毕后,相当于目标变量名有两个名称,即该目标原名称和引用名,且不能再把该引用名作为其他变量名的别名。ra=1;等价于a=1;•(3)不能建立数组的引用。•(4)不允许建立void类型的引用。•(5)不能建立引用的引用,不能建立指向引用的指针.。•(6)可以用const对引用加以限定,不许改变该引用的值。常引用•常引用声明方式:const类型标识符&引用名=目标变量名;•如果既要利用引用提高程序的效率,又要保护传递给函数的数据不在函数中被改变,就应使用常引用。•用这种方式声明的引用,不能通过引用对目标变量的值进行修改,从而使引用的目标成为const,达到了引用的安全性。【例】•inta;•constint&ra=a;•ra=1;//错误•a=1;//正确•这不光是让代码更健壮,也有些其它方面的需要。指针传递和引用传递•指针传递参数本质上是值传递的方式,它所传递的是一个地址值。值传递过程中,被调函数的形式参数作为被调函数的局部变量处理,即在栈中开辟了内存空间以存放由主调函数放进来的实参的值,从而成为了实参的一个副本。值传递的特点是被调函数对形式参数的任何操作都是作为局部变量进行,不会影响主调函数的实参变量的值。•引用传递过程中,被调函数的形式参数也作为局部变量在栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址。被调函数对形参的任何操作都被处理成间接寻址,即通过栈中存放的地址访问主调函数中的实参变量。正因为如此,被调函数对形参做的任何操作都影响了主调函数中的实参变量。•引用传递和指针传递是不同的,虽然它们都是在被调函数栈空间上的一个局部变量,但是任何对于引用参数的处理都会通过一个间接寻址的方式操作到主调函数中的相关变量。而对于指针传递的参数,如果改变被调函数中的指针地址,它将影响不到主调函数的相关变量。如果想通过指针参数传递来改变主调函数中的相关变量,那就得使用指向指针的指针,或者指针引用。C++中的引用和指针•★相同点:•1.都是地址的概念;•指针指向一块内存,它的内容是所指内存的地址;引用是某块内存的别名(java中的引用其实也是别名的意思)。★区别:1.指针是一个实体,而引用仅是个别名;•2.引用使用时无需解引用(*),指针需要解引用;•3.引用只能在定义时被初始化一次,之后不可变;指针可变;引用“从一而终”•4.引用没有const,指针有const,const的指针不可变;•5.“sizeof引用”得到的是所指向的变量(对象)的大小,而“sizeof指针”得到的是指针本身(所指向的变量或对象的地址)的大小;typeid(T)==typeid(T&)恒为真,sizeof(T)==sizeof(T&)恒为真,但是当引用作为成员时,其占用空间与指针相同(没找到标准的规定)。•6.指针和引用的自增(++)运算意义不一样;(7)引用被创建的同时必须被初始化(指针则可以在任何时候被初始化)。(8)不能有NULL引用,引用必须与合法的存储单元关联(指针则可以是NULL)。(9)一旦引用被初始化,就不能改变引用的关系(指针则可以随时改变所指的对象)。你如何决定在什么时候使用指针,在什么时候使用引用呢?首先,要认识到在任何情况下都不能用指向空值的引用。一个引用必须总是指向某些对象。因此如果你使用一个变量并让它指向一个对象,但是该变量在某些时候也可能不指向任何对象,这时你应该把变量声明为指针,因为这样你可以赋空值给该变量。相反,如果变量肯定指向一个对象,例如你的设计不允许变量为空,这时你就可以把变量声明为引用。“但是,请等一下”,你怀疑地问,“这样的代码会产生什么样的后果?”char*pc=0;//设置指针为空值char&rc=*pc;//让引用指向空值这是非常有害的,毫无疑问。我们以后将忽略一个引用指向空值的可能性。因为引用肯定会指向一个对象,在C++里,引用应被初始化。string&rs;//错误,引用必须被初始化strings(xyzzy);string&rs=s;//正确,rs指向s指针没有这样的限制。string*ps;//未初始化的指针//合法但危险•不存在指向空值的引用这个事实意味着使用引用的代码效率比使用指针的要高。因为在使用引用之前不需要测试它的合法性。•voidprintDouble(constdouble&rd)•{•coutrd;//不需要测试rd,它•}//肯定指向一个double值•相反,指针则应该总是被测试,防止其为空:•voidprintDouble(constdouble*pd)•{•if(pd)•{//检查是否为NULL•cout*pd;•}•}•总的来说,在以下情况下你应该使用指针,•一是你考虑到存在不指向任何对象的可能(在这种情况下,你能够设置指针为空),•二是你需要能够在不同的时刻指向不同的对象(在这种情况下,你能改变指针的指向)。如果总是指向一个对象并且一旦指向一个对象后就不会改变指向,那么你应该使用引用。•还有一种情况,就是当你重载某个操作符时,你应该使用引用。C++中返回引用和返回值的区别•intset(){returna;}•此时生成的是变量a的一个拷贝,即生成了一个临时变量,当这个变量使用完毕之后,变量就被销毁了,所以这种返回不能用作左值运算,如:set()=5;这是不正确的。•int&set()•{returna;}•在第二个例子中,返回的是引用,那么,就相当于返回的是变量a的别名,就可以对该变量操作,如赋值等等。set()=5;是正确的。•但是在引用返回时得注意一个问题,就是不能返回局部变量的引用,如:•int&set()•{inta;returna;}•此时就会调用出错,因为a是临时变量,函数结束是就自动销毁了,不能再创建别名了。但是将int&改成int就可以了。先看一个变量名作为函数参数的例子•#includeiostream.voidswap(intx,inty);intmain(){inta=2,b=3;swap(a,b);couta=aendl;coutb=bendl;return0;}voidswap(intx,inty){inttemp;temp=x;x=y;y=temp;}运行结果:a=2b=3#includeiostream.hvoidswap(int&x,int&y);//用引用传递参数intmain(){inta=2,b=3;swap(a,b);couta=aendl;coutb=bendl;return0;}voidswap(int&x,int&y)//函数定义要和函数原型一致{inttemp;temp=x;x=y;y=temp;}运行结果:a=3b=2再看一个引用作为函数参数的例子•将变量名作为函数参数时,在调用函数时,形参和实参不是占用同一个储存单元所以无法实现两个变量值的互换。而引用作为参数时,形参变量和实参变量占用同一个储存单元。交换了x和y就是交换了a和b,所以可以实现两个变量值的互换。•对于没有引用参数和使用了引用的参数的区别•如果我们把没有使用引用的参数认为是intx=a和inty=b(把变量a和变量b的值分别传给参数x和参数y),那么使用了引用的参数就是int&x=a和int&y=b了。也就是说x和y成为了变量a和变量b的“绰号”,对参数x和y的操作就如同对变量a和b的操作了。•“引用”与多态的关系•多态是面向对象的重要特性,简单点说:“一个接口,多种实现”,就是同一种事物表现出的多种形态。•引用是除指针外另一个可以产生多态效果的手段。
本文标题:C++中的引用
链接地址:https://www.777doc.com/doc-4220479 .html