• C++ 学习笔记之 引用


    一.定义:

      引用就是某一变量(目标)的一个别名,对引用的操作与对变量直接操作完全一样.

    二.用法:

        1. 基本用法

          例如: int & a = b;

        2. 引用作为函数返回值

          先看一个例子:

           1 #include <iostream>
           2 using namespace std;
           3 class Node{
           4     int x;
           5     public:
           6     Node(const Node & n){//去掉copy函数关于h的输出结果神奇般相同,原因未知
           7         x = n.x;
           8     }
           9     Node(int x=0):x(x){
          10 
          11     }
          12 };
          13 int temp ;
          14 int & F(){
          15     temp*=2;
          16     return temp;
          17 }
          18 int  F1(){
          19     temp*=2;
          20     return temp;
          21 }
          22 Node F2(){
          23     Node u(5);
          24     cout << &u << "  ";
          25     return u;
          26 }
          27 int main(){
          28     temp = 5;
          29     int &d = F(); //引用给引用,他们地址相同
          30     int e = F();  //引用给非引用,发生了复制
          31     const int & f = F();//把引用值赋值给常引用,他们的地址相同
          32     const int & g = F1();//对于内置数据类型,把非引用值赋值给常引用,他们的地址不同
          33     cout << &d << " " << &temp << endl;
          34     cout << &e << " " << &temp << endl;
          35     cout << &f << " " << &temp << endl;
          36     cout << &g << " " << &temp << endl;  
          37     const Node & h = F2();//对于类对象类型,把非引用值赋值给常引用,他们的地址可能不同    
          38     cout << &h << endl;     
          39     cout << d << " " << temp << endl;
          40     return 0;
          41 }
        3. 程序输出结果为:

          0x602194 0x602194
          0x7fffe0565418 0x602194
          0x602194 0x602194
          0x7fffe056541c 0x602194
          0x7fffe0565410 0x7fffe0565410
          80 80

            从结果中可以看到,当使用引用作为程序返回值并且将这个返回值赋值给引用类型时,他们的地址是相同的(都指向temp这个变量),其他情况都产生了值的赋值,发生了地址的变化。由此也可以看出,使用引用可以减少值的复制,特别是当需要传的数据特别大的时候。

        4.      另外,函数中返回非引用类对象赋值给const 引用变量时输出结果有些奇怪,不明白里面的copy函数为什么不调用但只加上就可以使他们的地址相同。
        5. 常引用 基本用法如下:
          int b = 4;
          const int a = b;

          使用常引用可以是引用的值不可修改。这样可以防止因误操作引发的数据修改,保证了安全性。

        6. 引用函数作为左值

          一般非引用函数都是只能作为右值,函数一旦计算完成那么它就是一个确定的常数。但引用函数不同。它既可作为左值,又可作为右值。

          int &d = ++F();

          相当于

          int A[10];
          int &array = A;

          这是它作为左值的应用。

          但当我执行

          int &d = F()++;

          这样会产生错误。错误信息为:

          error: invalid initialization of non-const reference of type 'int&' from an rvalue of type 'int'

          这个错误信息与执行

          int &d = 5;

          的错误信息一致,说明F()++操作实际上是相当于先把F()的值存到一个整型常量中,然后F()(相当于temp)的值加一.一个整型常量无法复制给int&类型。

          执行

          const int &d = F()++;(使用常引用)

          int d = F()++;(把常量值拷贝到变量中)

          才可以正常编译。

    三.注意事项:

          • 引用不能用于数组,但可以用在指针上

            如果尝试执行

            int A[10];
            int &array = A;

            编译器会报错:
            error: declaration of 'd' as array of references

            但我可以对指针用引用:

            int *p = A;
            int &array = p;

            编译成功。

            至于为什么不能对数组用引用,网上答案很多,我自己不能确定哪种答案是正确的,大家可以自行搜索相关问题。

          • 不要试图返回临时对象的引用,这样引用会成为无效引用,假如把返回值赋值给变量,那么程序可能会崩掉
          • 返回函数内部new分配的内存的引用或指针,这样的写法不推荐,很容易会造成内存泄漏(即无法正常的回收这块内存)
          • 注意常引用与普通引用之间的相互赋值问题
            1 temp = 5;
            2 const int t = 6;
            3 int &d = temp;
            4 const int &e = temp;
            5 const int &f = t;
            6 int &g = t;//编译错误

            常量变量都可以赋值给常引用,但只有变量值才可以给普通引用,若常量值给普通引用会发生编译错误。 

          • 另外记录一次在写C++作业的过程中偶然发现的一个问题,这加深了我对常引用以及ostream重载等的一些理解。点击跳转
  • 相关阅读:
    不过的小东东
    基础练习 特殊回文数
    基础练习 特殊回文数
    基础练习 特殊回文数
    web.input()与web.data()函数比较
    web.input()与web.data()函数比较
    web.input()与web.data()函数比较
    MFC 服务管理
    Fedora Documentation
    Centos7 安装vnc
  • 原文地址:https://www.cnblogs.com/Wade-/p/6476000.html
Copyright © 2020-2023  润新知