C++学习笔记 -- 引用

基础


  引用(reference)是作为某个对象的别名而出现的,不是拷贝,也不是指针.

  引用与其所指向的对象都代表同一片地址空间.

 1 #include<iostream>
 2 #include<string>
 3 using namespace std;
 4 
 5 class Animal{
 6     public:
 7         string name;
 8 };
 9 int main()
10 {
11     Animal a1;
12     Animal& a1_ref = a1;
13     cout<<&a1<<endl;         // 0x7fff06268920
14     cout<<&a1_ref<<endl;   // 0x7fff06268920
15     return 0;
16 }

  (1)在创建引用时,就要为其执行初始化操作;

  (2)引用在初始化之后就不能改变链接关系;

 1     Animal a1;
 2     Animal& a1_ref = a1;
 3     cout<<&a1<<endl;          //0x7ffff9617c90
 4     cout<<&a1_ref<<endl;    // 0x7ffff9617c90
 5     
 6     Animal a2;
 7     a1_ref = a2;       //这个操作并非是将a1_ref重新链接到a2,而是用a2来修改a1和a1_ref所指向空间的值
 8     cout<<&a2<<endl;         //0x7ffff9617ca0    
 9     cout<<&a1_ref<<endl;   //0x7ffff9617c90
10             

 

引用作为函数参数


 

  我们修改Animal类

class Animal{
    public:
        string name;
        void set_useRef(const string& n){     // 通过引用来传递
            name = n;
        }
        void set_unUseRef(const string n){   // 通过形参来传递
            name = n;
        }
};

  对于函数set_unUseRef,将实参拷贝后得到形参,使用拷贝得来的对象进行操作.

  

  对于函数set_useRef,实参是某个string对象的别名,形参也是某个对象的别名.因此name=n中,直接使用对象n的值来修改name.

  

引用作为函数返回值


 

  (1)当不使用引用作返回值时

 1 #include <iostream>
 2 #include<string>
 3 using namespace std;
 4 
 5 class Animal{
 6     public:
 7         string name;
 8         void set_useRef(const string& n){
 9             name = n;
10         }
11 }myAnimal;
12 
13 Animal name1(){
14     myAnimal.set_useRef("cat");
15     return myAnimal;
16 }
17 
18 int main()
19 {
20     Animal o1 = name1();
21     //Animal& o2 = name1();
22 
23     return 0;
24 }

  方法name1未使用引用来作为返回值类型时:先将myAnimal拷贝到临时变量中,然后使用这个临时变量对o1做赋值操作.赋值操作完成后,临时变量失效.

  

  对于示例代码中被注释掉的Animal& o2 = name1();,我使用g++ 4.8.2编译代码时不能通过.

  "error: invalid initialization of non-const reference of type ‘Animal&’ from an rvalue of type ‘Animal’"

  将o2作为一个要被是释放掉的临时变量的别名,在g++ 4.8.2看来时错误的.

  

  (2)使用引用作为返回值

 1 #include <iostream>
 2 #include<string>
 3 using namespace std;
 4 
 5 class Animal{
 6     public:
 7         string name;
 8         void set_useRef(const string& n){
 9             name = n;
10         }
11 }myAnimal;
12 
13 Animal& name2(){
14     myAnimal.set_useRef("dog");
15     return myAnimal;
16 }   
17 
18 int main()
19 {
20     Animal o3 = name2();
21     Animal& o4_ref = name2();
22     return 0;
23 }

  在Animal o3 = name2()中,使用一个对象o3来接纳name2的返回值.不会产生记录返回值的临时变量,直接使用myAnimal对象来对o3赋值.

  

  在Animal& o4 = name2()中,使用引用对象来接纳name2的返回值.

  

 

运算符重载与引用


  1)单目运算符( ++ , -- )

   返回值使用引用类型时.如果未使用引用类型时, ++(++obj)操作对obj的影响只有一次.

  2)双目运算符

 

   []赋值运算符( = , += , -= , *=, /= , %= , >>= , <<= ,  &=, |= , ^= )

   返回值设置为引用类型,可减少中间临时变量的产生.

   对于"="运算符,如果不使用引用类型的返回值,就不能进行连续赋值操作.(eg. a=b=c) 

 1 #include <iostream>                                          
 2 #include<string>                                             
 3 using namespace std;                                         
 4                                                              
 5 class Calculate{                                             
 6     public:                                                  
 7         int val;                                             
 8                                                              
 9     public:                                                  
10         Calculate(int c):val(c){}                            
11                                                              
12         Calculate& operator = (Calculate&);                  
13 };  
14 
15                                                              
16 Calculate& Calculate::operator = (Calculate& c){             
17     this->val = c.val;                                       
18     return *this;                                            
19 }

 

 

 

配置


 

  g++ 4.8.2

 

参考


  引用作为函数返回值

  不明出处的转载文章

posted @ 2014-12-09 19:41  Clint_Wu  阅读(208)  评论(3)    收藏  举报