部分转载:c++引用的使用

   我隐隐约约的感觉到,我们无法通过&取得引用的地址是因为编译器在背着我们做了些什么东西,你背着我到底做了什么??

例如:int a = 10; int &b = a; int *c = &a

这里把b看成临时变量的内存标识符(变量不就是代表一块内存吗)注意是看成,不一定是真的(只有写编译器的人才知道),临时变量里保存的就是a的地址&a),实际是b = &a (b在实现上就是指针),我们&b时,编译器给解释成b,我们b时,编译器给解释成*b,我们要是*b呢,就拒绝解释了,报错!于是我们&b得到的是b的内容&a,我们b得到的是*b也就是a,b就成了a的代名词,回忆我们c++里面用引用感觉比用指针方便,应该就是编译器给做了更多的工作吧,说引用方便,是指对于使用者而言,其实在底层实现上应该引用比指针更麻烦,明明存在个临时变量,不管他是不是属于引用,编译器明显隐藏了这个细节。在引用做函数返回值的时候(尤其当返回的是函数的临时变量时),这个时候才是引用的真正实现(我认为),返回的是变量的地址!我们return i; 返回了i的地址!于是出现了像

fun(4) = 2这样的表达式吧。。。。。。。说到底编译器还是没办法完全实现隐藏引用。。。(也许是为了效率逼不得已吧)。

调试完后想了半天才写的,因此没放代码

截取了网上一篇总结文章的精华部分,来全面的学习一下,

#include <iostream>
#include <stdio.h>

using namespace std;

void main(void)
{
    //测试引用是否可以赋以常量.
    /*
       int &a =100; //wrong
    */
   
    //考察引用和指针的使用区别
    /*  
        int a = 100;
           int *ptr;
           ptr = &a;
   cout<<*ptr<<endl;
          getchar();
   */
   
   //测试对引用取址返回的结果
   /*
         int a =100;
         int &b = a;
         cout<<b<<endl;
         cout<<&b<<endl;
         int &c = b;
         cout<<c<<endl;
         getchar();
        
   */
  
   //测试是否可以重新赋值
   /*
         int a = 100;
         int b = 200;
         int &c = a;
         cout<<a<<endl<<b<<endl<<c<<endl;
         c = b;
         cout<<c<<endl;
        
         getchar();
   */
   
    //说明引用的一种错误用法..........
    /*
         int a = 100;
         int &b = &a;
         cout<<a<<endl<<b<<endl;
         getchar();
    */
   
    /*
        char* str = "I am programming.";
        char*& rpchar = str;
        cout<<str<<endl<<rpchar<<endl;
        getchar();
    */
   
    //测试引用和指针混合的情况...
        typedef char* PChar;
        typedef char& RChar;
        typedef PChar& RPChar;
        PChar str = "I am programming.";

        /*
        RPChar rpchar; 
//wrong:not initialized..

        rpchar = str;
        */

        RPChar rpchar = str;
        cout<<str<<endl<<rpchar<<endl;
        getchar();
}
*/

 

对于int& a;引用实际是一种隐式指针,是方便编程而引入的,识别由编译器支持
.
    在函数的使用中.可把它理解为跟后面的结合. int (&a);
    在传递参数的过程中跟取地址值意思差不多.
/*  在函数内部使用过程中则相当与数值.你可把它看作便利的原因.

/*   其实引用&   是一个能自动被编译器逆向引用的常量型指针
总结:      ...
/*  A.常规使用:
/*                    1.   int a = 100;
/*                          int &b = a;
/*                    2.   int a = 100;
/*                          int &b = a;
/*                          int &c = b;
/*                    3.   int a = 100;
/*                          int &b;  //必须定义时赋值,不同于指针(int a = 100;
/*                                    // int *p; p =&a;) 
/*                          b = a;
/*                    4.   int &a = 100; //不可将常量赋予引用...

/*                          const int& a = 100;//可行,作全局看
/*                    5.    int a = 100;
/*                          int &b = a;
/*                          cout<<&b<<endl; //输出的是a(也是b)的地址..而不是指针
/*                                                   // 的地址...
/*                    6.   int a = 100;
/*                          int &b = a;
/*                          int *ptr;    
/*                          ptr = &a;
/*                          cout<<a<<b<<*ptr<<endl;  //结果是一样的..注意*ptr.
.
/*                    7.   int a =100;
/*                          int b= 200;
/*                          int &c = a;
/*                          c = b;      //引用可重新赋值...........
/*                        
/*B.较难的使用规则:
/*                    1.   系列错误用法:
/*                                       char* str = "I am programming.";
/*                         定义引用数组:int& a[3]; (定义指针数组:int* a[3]);
 
/*                         定义引用的指针:int&* a; (定义指针的指针:int** pt
r;
/*                         定义引用的引用:int&& a;
/*                    2.   可定义指针的引用:  int*& a = str;  //When it must  be initialized when definedv.  
          
/*C.引用在函数和对象域的使用
/*                    1.  做函数返回类型的应用:
(当然传递的参数类型为引用,那么是地址传递方式...)                  
/*                         int arr[3] = {1,2,3}; 
/*                         fook(2) = 100;    //函数返回的是引用,做左值时,编译器将其当作地址使用....
/*                                                   //而如返回的是常量,那当然不可赋值

                                  
/*                         int& fook(int index)  { return (arr[index]+1);}
/*
/*                    2.返回局部变量
/*                         int& fook(param)    {  int m = 100;   return m;  }    //在函数结束生命周期后,返回的地址将不可用.
/*
/*                   3.不好的对普通对象的引用
/*                     class MClass;
/*                     MClass* mcptr;
/*                     mcptr = new MClass(param);
/*                     if(!mcptr) MError("Constructing object failed.");
/*                     MClass& mcref = *mcptr;
/*                     也许上面的引用可以使你感觉更舒服的使用MClass: 如
/*                      mcref.function();而不必
/*                     (*mcptr).function();或mcptr->function();
/*                     可是相比之下,一个严重的问题来了:内存泄露..
/*                     因为引用不像指针那样明显:你很可能忘记:delete &mcref;

/*
/*                  4.对对象相关的参数的引用               
/*                    void fook(param1)     
/*                    {
/*                             param->function(noramlparam);
/*                    }
/*                   上面的程式中,我想传递一个对象的地址,从而使用对象的成员函
/*                    数..怎么办?
/*                     
/*                    void fook(MClass* mcpptrparam){};
/*                    恩,可以用一用:
/*                    MClass mcptr = new MClass(param);
/*                    fook(mcptr);
/*                    还有呢:
/*                    MClass mcobj;
/*                    fook(&mcobj);
/*                    当然你也可:
/*                    void fook(MClass& mcrefparam){};
/*                    这样引用的对象可在全局数据区、堆栈、栈
/*                  5.当然引用真的就是为了方便吗?.......
/*                    其实正如它在函数返回值里的应用,可由编译器识别为地址,在作为对象相关参数的
/*                    引用里亦存在同样的好处,指针的引用可替换指针的指针,多变的工作.... 

*********************************************************************************/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值