c++,简述你对引用的理解这里不是很理解

版权声明:本文为博主原创文章转载时请务必注明本文地址, 禁止用于任何商业用途 否则会用法律维权。 /stpeace/article/details/

      有言在先: 返回局部对象和简述你对引用的理解 就像返回局部变量的地址一样, 非常非常危险 要避免使用。  下面程序中有的地方返回了局部对象的指针 实际上也是危险的, 但本文先不讨论这個

     可见, 没有对象的拷贝 这样, 在fun函数中 就省略了拷贝的过程, 而是直接简述你对引用的理解a. 节省时间 节省空间, 真好

      看吧, 茬函数返回的时候 是返回简述你对引用的理解的, 这样 又少了一次拷贝。


       可见 对象简述你对引用的理解在C++中确实有很大的好处。比傳对象快捷高效 比指针更优美。

红色是我添加的其他地方是原莋者的。

主要是看了上面的这篇“从底层汇编理解 c++ 简述你对引用的理解实现机制“的文章之后觉得不错。就转了过来同时,对文中的程序都在自己的机器上验证了一下

如果要查看汇编后代码与源码的关系,我用的方法是:

简述你对引用的理解类型到底是什么它和指針有什么关系?它本身占用内存空间吗 带着这些疑问,我们来进行分析 先看代码:

  通过汇编查看代码如下:

  上面两条汇编的作用即:將x的地址存入变量b中,这不和将某个变量的地址存入指针变量是一样的吗

   所以从汇编层次来看,的确简述你对引用的理解是通过指针来實现的

   下面我们通过程序来验证,我们知道在程序一层我们只要直接涉及到简述你对引用的理解变量的操作,我们操作的总是被简述伱对引用的理解变量即编译器帮我们做了些手脚,总是在简述你对引用的理解前面加上*所以我们要读取真正的“简述你对引用的理解變量的值”,必须采取一定的策略好吧,我们就按照变量在栈中分布的特点来绕过编译器的这个特点

这个地方的结果和作者不一样,鈳以看后面的解释

  但是我们可以间接通过&y-1来得到b的地址,从而得到b的值:*(&y-1)  从结果可以知道b的值即x的地址,从而可以知道从地层实现來看,简述你对引用的理解变量的确存放的是被简述你对引用的理解对象的地址只不过,对于高级程序员来说是透明的编译器 屏蔽了簡述你对引用的理解和指针的差别。

  下面是程序的变量在内存栈中的分布简述你对引用的理解变量一样也占用内存空间,而且应该是4个芓节的空间

虽然从底层来说,简述你对引用的理解的实质是指针但是从高层语言级别来看,我们不能说简述你对引用的理解就是指针他们是两个完全不同的概念。有人说简述你对引用的理解是受限的指针这种说法我不赞同,因为从语言级别上指针和简述你对引用嘚理解没有关系,简述你对引用的理解就是另一个变量的别名对简述你对引用的理解的任何操作等价于对被简述你对引用的理解变量的操作。从语言级别上我们就不要去考虑它的底层实现机制啦,因为这些对你是透明的所以在面试的时候,如果面试的人问到这个问题可以先从语言级别上谈谈简述你对引用的理解,深入的话就从底层的实现机制进行分析而不能什么条件没有就说:简述你对引用的理解就是指针,没有差别......之类的回答

与原作者的不同,然后我就将上面的程序进行编译得到下面的结果:

上面基本每一句中都进行解释

從这儿可以看到我的机器上生成的汇编代码是将x的地址赋给了堆栈中地址所在处的下一个地址单元。

从printf所生成的汇编代码处我们也可以看箌是按照逆序来计算的(&*(&y-1), &y-1, &y, x)这也印证了C标准中提到的函数的参数是逆序入栈的。

这样就和作者的符合起来了

前言:简述你对引用的理解是C++一個很重要的特性最近看了很多有关简述你对引用的理解的资料和博客,故在此对简述你对引用的理解的相关知识进行总结

简述你对引用嘚理解顾名思义是某一个变量或对象的别名,对简述你对引用的理解的操作与对其所绑定的变量或对象的操作完全等价

1.&不是求地址运算苻而是起标志作用

2.简述你对引用的理解的类型必须和其所绑定的变量的类型相同

5 int &b=a; //错误,简述你对引用的理解的类型必须和其所绑定的变量的类型相同

3.声明简述你对引用的理解的同时必须对其初始化否则系统会报错

4 int &a; //错误!声明简述你对引用的理解的同时必须对其初始化

4.简述你对引用的理解相当于变量或对象的别名,因此不能再将已有的简述你对引用的理解名作为其他变量或对象的名字或别名

5.简述你对引用嘚理解不是定义一个新的变量或对象因此内存不会为简述你对引用的理解开辟新的空间存储这个简述你对引用的理解

语法:类型 (&简述你對引用的理解名)[数组中元素数量]=数组名;
语法:类型 *&简述你对引用的理解名=指针名;//可以理解为:(类型*) &简述你对引用的理解名=指针名,即将指针的类型当成类型*

A.简述你对引用的理解作为函数的参数

1.当用简述你对引用的理解作为函数的参数时其效果和用指针作为函数参数嘚效果相当。当调用函数时函数中的形参就会被当成实参变量或对象的一个别名来使用,也就是说此时函数中对形参的各种操作实际上昰对实参本身进行操作而非简单的将实参变量或对象的值拷贝给形参

2.通常函数调用时系统采用值传递的方式将实参变量的值传递给函数的形参变量。此时系统会在内存中开辟空间用来存储形参变量,并将实参变量的值拷贝给形参变量也就是说形参变量只是实参变量的副本而已;并且如果函数传递的是类的对象,系统还会调用类中的拷贝构造函数来构造形参对象而使用简述你对引用的理解作为函數的形参时,由于此时形参只是要传递给函数的实参变量或对象的别名而非副本故系统不会耗费时间来在内存中开辟空间来存储形参。洇此如果参数传递的数据较大时建议使用简述你对引用的理解作为函数的形参,这样会提高函数的时间效率并节省内存空间

3.使用指針作为函数的形参虽然达到的效果和使用简述你对引用的理解一样但当调用函数时仍需要为形参指针变量在内存中分配空间,而简述你對引用的理解则不需要这样故在C++中推荐使用简述你对引用的理解而非指针作为函数的参数

4.如果在编程过程中既希望通过让简述你对引用嘚理解作为函数的参数来提高函数的编程效率,又希望保护传递的参数使其在函数中不被改变则此时应当使用对常量的简述你对引用的悝解作为函数的参数。

5.数组的简述你对引用的理解作为函数的参数:C++的数组类型是带有长度信息的简述你对引用的理解传递时如果指明嘚是数组则必须指定数组的长度

常简述你对引用的理解不允许通过该简述你对引用的理解对其所绑定的变量或对象进行修改

6 new_a=11;//错误!不允许通过常简述你对引用的理解对其所绑定的变量或对象进行修改

运行上面的程序编译器会报错

这是由于func1()和“Tomwenxing”都会在系统中产生一个临时对潒(string对象)来存储它们,而在C++中所有的临时对象都是const类型的而上面的程序试图将const对象赋值给非const对象,这必然会使程序报错如果在函数func2嘚参数前添加const,则程序便可正常运行了

C.简述你对引用的理解作为函数的返回值

1.简述你对引用的理解作为函数的返回值时必须在定义函数時在函数名前将&

2.用简述你对引用的理解作函数的返回值的最大的好处是在内存中不产生返回值的副本

case 1:用返回值方式调用函数(如下图,圖片来源:伯乐在线):

返回全局变量temp的值时C++会在内存中创建临时变量并将temp的值拷贝给该临时变量。当返回到主函数main后赋值语句a=fn1(5.0)会把臨时变量的值再拷贝给变量a

case 2:用函数的返回值初始化简述你对引用的理解的方式调用函数(如下图,图片来源:伯乐在线)

这种情况下函数fn1()是以值方式返回到,返回时首先拷贝temp的值给临时变量。返回到主函数后用临时变量来初始化简述你对引用的理解变量b,使得b成为該临时变量到的别名由于临时变量的作用域短暂(在C++标准中,临时变量或对象的生命周期在一个完整的语句表达式结束后便宣告结束吔就是在语句float &b=fn1(5.0);之后) ,所以b面临无效的危险很有可能以后的值是个无法确定的值。

 如果真的希望用函数的返回值来初始化一个简述你对引用的理解应当先创建一个变量,将函数的返回值赋给这个变量然后再用该变量来初始化简述你对引用的理解:

 case 3:用返回简述你对引用嘚理解的方式调用函数(如下图,图片来源:伯乐在线)

这种情况下函数fn2()的返回值不产生副本,而是直接将变量temp返回给主函数即主函數的赋值语句中的左值是直接从变量temp中拷贝而来(也就是说c只是变量temp的一个拷贝而非别名) ,这样就避免了临时变量的产生尤其当变量temp昰一个用户自定义的类的对象时,这样还避免了调用类中的拷贝构造函数在内存中创建临时对象的过程提高了程序的时间和空间的使用效率。

case 4:用函数返回的简述你对引用的理解作为新简述你对引用的理解的初始化值的方式来调用函数(如下图图片来源:伯乐在线)

这种凊况下,函数fn2()的返回值不产生副本而是直接将变量temp返回给主函数。在主函数中一个简述你对引用的理解声明d用该返回值初始化,也就昰说此时d成为变量temp的别名由于temp是全局变量,所以在d的有效期内temp始终保持有效故这种做法是安全的。

3.不能返回局部变量的简述你对引用嘚理解如上面的例子,如果temp是局部变量那么它会在函数返回后被销毁,此时对temp的简述你对引用的理解就会成为“无所指”的简述你对引用的理解程序会进入未知状态。

4.不能返回函数内部通过new分配的内存的简述你对引用的理解虽然不存在局部变量的被动销毁问题,但洳果被返回的函数的简述你对引用的理解只是作为一个临时变量出现而没有将其赋值给一个实际的变量,那么就可能造成这个简述你对引用的理解所指向的空间(有new分配)无法释放的情况(由于没有具体的变量名故无法用delete手动释放该内存),从而造成内存泄漏因此应當避免这种情况的发生

5当返回类成员的简述你对引用的理解时,最好是const简述你对引用的理解这样可以避免在无意的情况下破坏该类的成員。

6.可以用函数返回的简述你对引用的理解作为赋值表达式中的左值

7 return value[n];//返回的简述你对引用的理解所绑定的变量一定是全局变量不能是函數中定义的局部变量

在C++中,简述你对引用的理解是除了指针外另一个可以产生多态效果的手段也就是说一个基类的简述你对引用的理解鈳以用来绑定其派生类的实例

ptr只能用来访问派生类对象中从基类继承下来的成员如果基类(类Father)中定义的有虚函数那么就可以通过在派生类(类Son)中重写这个虚函数来实现类的多态。

1.在简述你对引用的理解的使用中单纯给某个变量去别名是毫无意义的,简述你对引用嘚理解的目的主要用于在函数参数的传递中解决大块数据或对象的传递效率和空间不如意的问题

2.用简述你对引用的理解传递函数的参数,能保证参数在传递的过程中不产生副本从而提高传递效率,同时通过const的使用还可以保证参数在传递过程中的安全性

3.简述你对引用的悝解本身是目标变量或对象的别名,对简述你对引用的理解的操作本质上就是对目标变量或对象的操作因此能使用简述你对引用的理解時尽量使用简述你对引用的理解而非指针

我要回帖

更多关于 简述你对引用的理解 的文章

 

随机推荐