C ++中的变量和引用有什么区别?

What is the difference between a variable and a reference in C++?

本问题已经有最佳答案,请猛点这里访问。

我所知道的事实:

  • C++中有三种变量:变量、指针和引用。
  • 变量有点像存储实际数据的内存的标签。
  • 指针存储变量的地址。
  • 引用是变量的别名。
  • 我的问题:

  • 通过观察,变量名和引用的使用是可交换的。是真的吗?
  • 将变量名作为参数传递与传递引用有什么区别?例如。,

    void func(int a);vs void func2(int&b);

  • 非常感谢!


    以下是理解差异的方法:好的。型

      百万千克1可以改变状态的对象也称为"变量"。百万千克1百万千克1指针是对象(变量或非变量)。他们有一个国家。百万千克1百万千克1参考文献是"昵称"。它们没有状态,但公开引用对象的状态(这就是为什么不能重新分配引用,它不是实际对象的原因)。百万千克1

    现在,在某些情况下,引用可以实现为指针,但是从语言的角度来看,引用不仅仅是指针,它们实际上是已经存在的对象的附加名称。好的。型

    由于指针是对象,并且具有状态,向函数传递指针将复制该状态、指针的状态,而不是指针的状态。但是,引用没有状态,所以如果您传递一个对函数的引用,它就是您传递的引用对象(通过复制)。好的。型

    By observation, the use of variables names and references is
    exchangeable. Is that true?

    Ok.

    "参考文献就是昵称"是理解参考文献的最佳方式。好的。型

    What is the difference between passing a variable name as parameter
    and passing a reference? e.g.,

    Ok.

    void func(int a); vs void func2(int& b);

    Ok.

    第一个实现要求传递对象的副本。也就是说,内部func()可以对执行任何操作,而不必更改传递给func()的对象,因为内部func()复制了该对象并操作了副本,而不是原始副本。好的。型

    第二个实现要求"已有对象的昵称"。首先,对象必须存在,如果传递,它的昵称将在函数内部创建。这个昵称,即引用b,仍然是原始对象的昵称。这意味着对b所做的任何操作都将影响传递给func2()的原始对象。好的。型

      百万千克1func()签名说"我需要这个数据,但我不会修改传递的原始对象。"百万千克1百万千克1func2()签名说"我需要一个我肯定要修改的对象,传递它以便我修改它"。百万千克1

    奖金阶段:好的。型

    此时,如果您还不了解const,这可能很有用:在函数签名中,const与引用一起用于指定"只读"的参数。好的。型

    让我澄清一下:好的。型

    1
    void func3( const int& b)

    这里func3说:"我需要访问一个对象,但实际上我不会复制它。但是我保证我不会改变那个目标。好的。型

    那么,我们为什么需要这个?因为有些对象的复制成本很高。int的复制成本很低,所以大多数人只需传递它,func()和func3()基本上是等效的(取决于实现,但通常是真的)。好的。型

    但是,如果我们想要传递一个非常大的对象,比如数据缓冲区,我们真的不想一次又一次地复制它,只是为了应用一些算法。所以我们想通过引用来传递它。但是,根据函数的不同,有时您希望提取信息并使用它,因此您只需要对参数进行"只读"访问。在本例中,您使用const Object&。但是,如果需要将算法应用于传递的对象,则需要能够修改它,这可以称为"写访问"。在这种情况下,需要使用普通引用。请求一个副本基本上意味着您想要操作一个与传递的对象状态相同的对象,但不是传递的对象。好的。型

    总结如下:好的。型

      百万千克1func( T object )我想要一份t型对象的副本;百万千克1百万千克1func( T& object ):我想对t类型的对象拥有"写访问权"——假设我将修改该对象!(二)百万千克1百万千克1func( const T& object ) or func( T const & object ) // which are the same:我想读取一个对象的状态,但我保证不会修改它,我想"只读"访问。百万千克1

    实际上,使用const_cast<>可能会违反"只读"保证,但这是另一回事,它只在一些非常狭窄的情况下使用。好的。型

    最后你需要知道的是,如果你有一个成员函数,那么你可以做:好的。型

    1
    2
    3
    4
    class K{
    public:
         void func() const; // see the const?
    };

    在这种特定的情况下,您所说的是函数内部,它基本上等同于:void func(const k*this);好的。型

    在这种情况下,您可以看到这是一个指针,但它指向一个常量对象。这意味着func()保证它所属的对象(this)永远不会通过此函数进行修改(除了某些特定情况,请参见mutable关键字,另一个长篇故事)。好的。型好啊。


    假设您具有以下两个功能:

    1
    2
    3
    4
    5
    6
    7
    void addone(int a) {
       a += 1;
    }

    void addone_bis(int &a) {
      a += 1;
    }

    如果调用main函数中的第一个函数,该值只在函数addone中更改,而不是在主函数中更改,而如果调用addone_bis函数,a的值也在main函数中更改。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int main() {
       int test_a = 10;
       int test_b = 11;

       addone(test_a);
       // test_a still equals 10.

       addone_bis(test_b);
       // test_b now equals 12.

    }

    我正确回答了你的问题吗?


    第一个例子就是所谓的传递值。这意味着实际值的一个副本被传递到例程中。

    当以第二个示例的方式传递时,这就是所谓的传递引用。引用实质上是将变量传递到例程中,这样被调用的例程就可以修改其实际值,而无需取消引用。