c++ 的引用

来源:互联网 发布:js设置滚动条置顶 编辑:程序博客网 时间:2024/06/05 15:33
 
转于:http://blog.csdn.net/bizhu12/article/details/6666176
 
 
c++func

            C++的引用具备指针的所有功能,不过引用与指针的区别在于引用在定义时必须要初始化,因为引用对象不许为空,若对象可以为空,则定义指针变量,int i=9;int &s = i;

定义引用指向了i;其实引用相当于我们所说的"别名",是所指向的变量的别名,引用与变量共用一个内存地址

如:

[cpp] view plaincopyprint?
  1. int a ; 
  2. int &b = a; 

他们的内存地址都是一块地址


只要内存地址的值发生改变,这两个变量的值都会改变,下面可以验证一下

代码

[cpp] view plaincopyprint?
  1. #include <iostream> 
  2. using namespace std; 
  3. int main() 
  4.    int a ; 
  5.    int &b = a; 
  6.  
  7.    a = 100; //内存地址值得改变,变量b的值也变 
  8.    cout << "b = " << b <<endl; 
  9.     
  10.    b = 200;//a的值也变 
  11.    cout << "a = " << a << endl; 
  12.    return 0; 
[cpp] view plaincopyprint?
  1.   

执行的结果:


    当一个引用初始化时指定到了一个变量,则这个引用的地址永远是该变量的地址,不会再改变,如果该引用再次指向别的变量,则只是把这个变量的值赋给该引用,

引用的地址不会改变,并且引用初始化时指向的变量的值也会改变,

   在C++中还可以定义一个类的对象的引用,与对象共享一块地址,不能定义第一个类的引用,因为类只是一种类型,没有内存地址,引用必须指向一块

内存地址,

[cpp] view plaincopyprint?
  1. #include <iostream> 
  2. using namespace std; 
  3.  
  4. class Test 
  5. public
  6.     void set(int val); 
  7.     int  Get(); 
  8. private
  9.     int  i; 
  10. }; 
  11.  
  12. void Test::set(int val) 
  13.     i = val; 
  14.  
  15. int Test::Get() 
  16.     return i; 
  17.  
  18. int main() 
  19.    Test  T; //定义类的对象 
  20.    Test  &rT = T; //定义类的对象的引用 
  21.    //Test  &rTest = Test  //不能这样定义一个类的引用 
  22.     
  23.    T.set(20); 
  24.    cout << "对象的引用的rT.Get()值:" << rT.Get() << endl;  
  25.  
  26.    rT.set(40); 
  27.    cout << "对象的T.Get()值:" << T.Get() << endl; 
  28.    return 1; 


执行的结果:

    指针进行删除后一般要把指针指向空,而引用不需要,不管怎么样,引用永远指向初始化的内存空间,就算是指针的引用,指针进行删除
操作后,引用的内存地址还是不变,不过指针删除后内存的数据也被删除,如果对象在栈中,当对象超出作用域后,引用和对象一起消失,

如果对象在堆中,堆的空间必须使用指针访问,因为堆空间一般是手动分配,在分配内存时定义一个指针指向分配的空间,所以堆空间只能

指针访问,没必要用引用,不过可以定义指针引用但如果删除指针后,引用的地址不变,只是内存的数据被删除


       引用常见的使用是用于传递函数参数,使用时很好用,参数的传递常见的有按值传递,按地址传递和引用传递,在说引用传递前先看看前面的两种,

1. 按值传递

先看一下例子

看执行的结果,通过set()函数后主函数的值还是不变,这是为什么?因为按值传递,只是把主函数a的值给了set()函数的a值,这两个a的地址不是同一个地址,

在执行的过程中,会把主函数a的地址的数据拷贝给set函数a的地址,通过调式可以看一下这两个a的地址

主函数a的地址:

set()函数a的地址

可以看到是不同的地址

2. 按地址传递

   可以看到主函数a的值通过set()函数后已经改变,其实这时候这两a是同一块内存地址,set()函数中的参数a是指针指向主函数a的地址,所以是同一

块内存地址,对set()中a的值修改,主函数中的a的值也改变,因为同那块内存地址的数据改变了;不过set()函数中要使用到指针,比较麻烦而且难使用,

所以就有了引用传递

3. 引用传递

  主函数中的a值经过set()函数后一样会发生改变,而且使用起来方便,不像使用指针那样难以管理,这就是使用引用比使用指针的好处

这样的话,只需要在函数参数中添加引用,这样就可以解决无法返回对个值,只需要把要返回的变量作为引用传递就可以改变多个变量的值

引用的传递在类的对象的应用中是相当有用的...

下面是一个视频资料的截屏

说明了按值传递与其他两种传递的不同之处

这里是使用引用容易出错的地方

这是个引用传递对象,在fun()函数中的对象是区部对象,当fun()函数结束后这个对象也不存在了,所以在主函数中的类对象引用接收fun()函数的对象是不存在的,所以输出一个

随机值,那为什么下面这个就能正确输出?

其实这是在fun()函数返回时是使用了按值传递,fun()前没有了&,所以在主函数的引用接收到的fun()函数对象的值,

所以是正确的

0 0
原创粉丝点击