【问题标题】:What is a reference variable in C++?什么是 C++ 中的引用变量?
【发布时间】:2011-02-15 11:56:43
【问题描述】:

C++ 中引用变量的简要定义是什么?

【问题讨论】:

  • 引用很有用,因为它们强制使用初始化的内存(即它们不能引用 null,正常使用时)。
  • 引用只是const 指针的语法糖(不一定是指向常量的指针)。对 NULL 的引用没有特别的保护措施,它会导致与取消引用 NULL 指针相同的未定义行为。你可以说调用者通过取消引用 NULL 并传递 NULL 引用来违反 C++ 标准,而不是通过将 NULL 指针作为不可为空的参数传递来违反 API 协定,但在技术上和典型的运行时行为中没有区别无论如何。

标签: c++ reference variables


【解决方案1】:

第 79 ~ 80 页 C++ Primer 第 5 版。

对象:具有类型的内存区域

变量:命名对象或引用

参考:另一个对象的别名。

【讨论】:

    【解决方案2】:

    引用是对象的替代名称。引用变量为先前定义的变量提供别名。引用声明由一个基类型和一个等同于变量名的引用变量组成。

    【讨论】:

      【解决方案3】:

      引用变量(let a),为了便于理解,说一下变量的另一个名字(let x),与x的内存位置完全相同。

      int &a = x; 表示 a 与 x 拥有相同的内存位置。

      例如,假设两个室友共享同一个房间。一个朋友的名字是x,另一个朋友的名字是a。如果a 将放置在房间中的桌子的位置从(x,y,z) 更改为(x1,y1,z1),那么朋友x 也可以看到更改,反之亦然。

      【讨论】:

        【解决方案4】:

        引用变量变量名别名

        它与指针的区别如下:

        1. 您不能有 NULL 引用。您必须始终能够假定引用已连接到合法存储。
        2. 一旦一个对象的引用被初始化,它就不能被更改为指向任何另一个对象,而如果是指针,我们可以随时让它指向任何其他对象。
        3. 必须在创建引用时对其进行初始化。可以随时初始化指针。

        【讨论】:

          【解决方案5】:

          引用变量允许两个变量名寻址同一个内存位置:

          int main()
          {
              int var1;
          
              // var2 is a reference variable, holds same value as var1
          
              int &var2 = var1;
              var1 = 10;
          
              std::cout << "var1 = " << var1 << std::endl;
              std::cout << "var2 = " << var2 << std::endl;
          }
          

          资源:LINK

          【讨论】:

            【解决方案6】:

            引用是用于初始化它的对象的替代标签、别名。一旦引用被初始化,就不能将其更改为其他对象的替代标签或别名。初始化后,引用或对象变量可以互换使用。

            引用具有指向对象的 const 指针的一些特征,即它在定义时被初始化。虽然它引用或指向的内容可以更改,但引用或 const 指针本身不能更改。但是,由于引用是替代标签或别名,它可能会或可能不会作为数据对象实际存在,这与 const 指针不同,除非编译器可以优化它,否则它可能会存在。即使编译器将引用创建为实际实体,这也是编译器的内务管理,应该被忽略,因为它不像翡翠城幕后的人那样正式存在。

            以下代码示例给出了使用指针和常量指针比较和对比引用的示例:

            int myInt;           // create a variable of type int, value not initialized
            int myInt2 = 3;      // create a second variable of type int with a value of 3
            int &rInt = myInt;   // create a reference to the variable of type int, myInt
            
            rInt = 5;            // myInt now has a value of 5, the reference is an alias for myInt
            rInt++;              // myInt now has a value of 6, the reference is an alias for myInt
            rInt = myInt2;       // myInt now has the same value as myInt2, a value of 3
            int *pInt = &rInt;   // pInt points to myInt
            (*pInt)++;           // increments myInt
            pInt++;              // increments the pointer which formerly pointed to myInt
            
            int &rInt2;          // error C2530: 'rInt2' : references must be initialized
            int *pInt2;          // just fine, uninitialized pointer is ok
            int * const pInt3;   // error C2734: 'pInt3' : const object must be initialized if not extern
            int * const pInt4 = &myInt;  // define and initialize const pointer
            pInt4 = &myInt2;     //  error C3892: 'pInt4' : you cannot assign to a variable that is const
            

            实际上有两种引用:lvalue 引用和rvalue 引用。

            lvalue 引用与 C++11 之前的 C++ 语言中的引用相同。在 C++11 中引入了 rvalue 引用,以允许引用临时对象以帮助进行移动而不是复制以及复制是错误方法但移动是正确方法的其他一些操作。

            例如,以下简单源代码行中左值引用和右值引用的比较。因为这些是int 引用,这意味着非整数值的赋值会导致编译器进行转换,从而产生一个临时变量。 rvalue 引用可以绑定到临时变量,lvalue 引用不能。

            // assign a double to an int causing creation of temporary    
            int &rIntd1 = 1.2;   // error C2440: 'initializing' : cannot convert from 'double' to 'int &'
            int &&rIntd2 = 1.2;  // warning C4244: 'initializing' : conversion from 'double' to 'int', possible loss of data
            
            rInt = rIntd2;       // myInt from the code above now has a value of 1, 1.2 was truncated when converting from double to int
            

            【讨论】:

              【解决方案7】:

              引用变量指针变量对机器来说是完全一样的(编译器会生成相同的机器码)。

              据我所知,使用引用变量优于指针变量的最明显优势:

              1. 易于理解(无地址,取消引用各种令人头疼的事情)
              2. 为您节省一点打字,因此可能不易出错

              在下面的代码中,左侧使用引用变量,右侧使用指针变量。它们对机器来说是一样的,但是您会看到 using 引用变量为您节省了一点打字时间。

              Reference variable           Pointer variable
              int a = 1;         ~~~~~~    int a = 1;
              int &b = a;        ~~~~~~    int *b = &a;
              b = 2;             ~~~~~~    *b = 2;
              cout << a << '\n'  ~~~~~~    cout << a << '\n'
              ==============================================
              2                  ~~~~~~    2
              

              【讨论】:

                【解决方案8】:

                【讨论】:

                • 很好的常见问题解答,“尽可能使用引用,必要时使用指针。”
                【解决方案9】:

                这是一个引用另一个变量的变量:

                int foo;
                int& bar = foo;
                

                bar 现在是一个引用,也就是说bar 保存了foo 所在的内存位置。

                更多信息请参见here

                【讨论】:

                • 技术上不是。如果 bar 是一个变量,您可以获得它的地址。引用是另一个变量的别名(不是地址,因为这意味着编译器需要插入取消引用操作)。当它被编译出来时,bar 可能只是被 foo 替换。
                • 您的文字描述了一个指针。引用不保存任何内存位置,并且可能不需要任何存储。 (在您的示例中,bar 可能不使用任何存储空间)。
                【解决方案10】:

                引用变量为先前定义的变量提供别名(替代名称)。 例如:

                float total=100;
                float &sum = total;
                

                这意味着totalsum 是相同的变量。

                cout<< total;
                cout << sum;
                

                两者都将给出相同的值,100。这里&amp; 运算符不是地址运算符; float &amp; 表示对浮点数的引用。

                【讨论】:

                  【解决方案11】:

                  Wikipedia article 的第一段可以很容易地作为一个简短的定义:

                  在 C++ 编程语言中,引用是一种简单的引用数据类型,它不如从 C 继承的指针类型强大但更安全。

                  并引用同一篇文章:

                  C++ 引用在几个基本方面不同于指针:

                  • 定义后不能直接引用引用对象;其名称的任何出现都直接引用它所引用的对象。

                  • 一旦创建了引用,以后就不能再引用另一个对象了;它不能被重新安装。这通常使用指针来完成。

                  • 引用不能为空,而指针可以;每个引用都指向某个对象,尽管它可能有效也可能无效。

                  • 引用不能未初始化。因为不可能重新初始化引用,所以它们必须在创建后立即初始化。特别是,局部变量和全局变量必须在定义它们的地方进行初始化,并且作为类实例数据成员的引用必须在类的构造函数的初始化列表中进行初始化。

                  进一步阅读:

                  【讨论】:

                  • 维基百科不是很权威的来源。
                  【解决方案12】:

                  reference 是一个实体,它是另一个 object 的别名。

                  reference 不是 variable,因为 variable 仅由 object 的声明引入。 object 是一个存储区域,在 C++ 中,引用不会(必然)占用任何存储空间。

                  由于 objectsreferences 在 C++ 中是不同的实体组,因此术语“引用变量”没有意义。

                  【讨论】:

                  • 嗯,还不是变量。很好,C++0x 解决了这个问题 - 这是标准中长期存在的问题。请参阅open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#633 并查看 n3090,它已并入 FCD。无论如何,为了完整起见,您可以提到引用也可以引用函数。 +1 技术准确性:)
                  • 抱歉恢复旧帖。这是否意味着在 C++11/14/17 中谈论int&amp; b = a 时我可以安全地使用术语“引用变量”?
                  • 自 C++11 起,变量表示引用或对象。参见 C++14 中的 [basic]/6 例如:“variable 是由非静态数据成员或对象以外的引用的声明引入的。变量的名称,如果any, 表示引用或对象。”
                  • 好答案 - 任何花费大量时间了解完全基于对象的语言(如 Python)的人都会告诉您,即使是 first 名称给一个对象在技术上是一个引用 :-) object 本身是无名的,只是用某种方法来创建一个对象是没有意义的。
                  猜你喜欢
                  • 1970-01-01
                  • 2011-08-30
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2010-10-31
                  • 1970-01-01
                  • 1970-01-01
                  • 2016-06-03
                  相关资源
                  最近更新 更多