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

use*_*047 1 c++ variables reference

我所知道的事实:

  1. C++中有三种类型的变量:变量,指针和引用.
  2. 变量是存储实际数据的存储器的标签.
  3. 指针存储变量的地址.
  4. 引用是变量的别名.

我的问题:

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

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

太感谢了!

Kla*_*aim 6

这是一种理解差异的方法:

  • 可以改变状态的对象也称为"变量".
  • 指针是对象(可变或不可变).他们有一个州.
  • 引用是"昵称".它们没有状态,但是暴露了引用对象的状态(这就是为什么你不能重新分配引用,它不是一个实际的对象).

现在,在某些情况下,引用可能被实现为指针,但从语言的角度来看,引用只是不是指针,它们实际上是已存在的对象的附加名称.

由于指针是对象,并且具有状态,因此将指针传递给函数将复制该状态,指针的状态,而不是指针的状态.但是,引用没有状态,因此如果传递对函数的引用,则它是您传递的引用对象(通过复制).

通过观察,变量名称和引用的使用是可交换的.真的吗?

"引用是昵称"是理解引用的最佳方式.

传递变量名作为参数和传递引用有什么区别?例如,

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

第一个实现请求传递的对象的副本.也就是说,内部func()可以对a执行任何操作,而不更改传递给func()的对象,因为内部func()创建了该对象的副本并操纵副本,而不是原始副本.

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

  • func()签名说"我需要这些数据,但我不会修改传递的原始对象."
  • func2()签名说"我需要一个我肯定会修改的对象,传递它以便我可以修改它".

奖金阶段:

此时,如果您还不知道const,那可能有用:在函数签名const中使用引用来指定"只读"的参数.

让我澄清一下:

void func3( const int& b??
Run Code Online (Sandbox Code Playgroud)

这里func3说:"我需要访问一个对象,但实际上我不会复制它.但我保证我不会改变那个对象".

那么,为什么我们需要呢?因为某些对象复制起来很昂贵.int复制很便宜,所以大多数人只会传递它,而func()和func3()基本上是等价的(取决于实现但通常是真的).

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

总结一下:

  • func( T object ) :我想要一个类型为T的对象的副本;
  • func( T& object ) :我希望对类型为T的对象进行"写访问" - 假设我将修改该对象!
  • func( const T& object ) or func( T const & object ) // which are the same :我想读取一个对象的状态,但我向你保证我不会修改它,我想要"只读"访问.

实际上,可以使用"只读"保证,const_cast<>但这是一个不同的故事,它仅用于一些非常非常狭窄的情况.

你需要知道的最后一件事是,如果你有一个成员函数,那么你可以这样做:

class K{
public:
     void func() const; // see the const?
};
Run Code Online (Sandbox Code Playgroud)

在这个特定的情况下,你所说的是函数内部,它基本上等同于:void func(const K*this);

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