'pass variable by reference' 是如何运作的?

How does 'pass variable by reference' work?

代码如下:

// 'type' here indicates certain variable type, int, char, struct, etc.
void foo(type &a, type b) {...}
type a = ...;
type b = ...;
type &c = a;
foo(a, b);
foo(c, b);

编译没有问题。但是从字面上看,foo的第一个参数是type&的,这是一个参考,而foo(c, b)在我看来比foo(a, b)更一致,因为c是一个参考type& 本身但 a 只是一个 type 变量。

例如void bar(int*)int *a; int b由于参数类型不同,只能将a传递给bar而不是b

传递引用案例中这种不一致的潜在机制是什么?

引用通常仅作为指向内存地址的指针来实现。将变量分配给引用会分配变量的内存地址。将引用分配给引用会复制内存地址。如果您将引用视为指针(逻辑上是这样,只是有额外的编译器强制限制),您的示例代码实际上是在执行以下操作:

void foo(type *a, type b) {...}

type a = ...;
type b = ...;
type *c = &a;
foo(&a, b);
foo(c, b);

在您的示例中,a 属于 type 类型,b 也是。 c 属于 type&.

类型

当您通过传递 a 作为第一个参数来调用该函数时,它会获取对您的 a 副本的引用。当您使用 c 作为参数调用它时,由于 c 已经是一个引用,因此不必 reference 因为它已经是一个引用。

引用曾经有一些不同,但现在主要只是一种比指针更方便的语法。使用指针,您的示例如下所示:

void foo(type *a,type b) {...}
type a = ...;
type b = ...;
type *c = &a;
foo(&a, b); // the compiler is really doing this for you when you use references
foo(c, b);

唯一 区别(在现代编译器上) 是编译器为您执行引用和取消引用并且不让pointer 为 null (除非你做一些你不会做的有创意的事情).

如果从语言上考虑它有帮助,你的函数是说 "please give me a reference to a type instance and a copy of a type instance."

您的第一个电话是 "here, grab a reference to this type instance, and here's a copy of this other type instance."

你的第二个电话是 "here, grab this reference to a type instance, and here's a copy of this other type instance."

您混淆了变量的声明及其用法。

之后:

type a = x;
type &c = a;

情况和你写的完全一样:

type c = x;
type &a = c;

在这两种情况下都有一个变量,它有两个名称,ac

因为 C++11 有一个区别,decltype(a) 将引用作为类型的一部分

当您在其后的表达式中使用 ac 时,它指的是该变量。

当你有 void foo(type &p, type q)(更改名称以避免混淆)时,如果你调用 foo(a, b);,那么名称 p 将成为参数 a 的另一个名称.一个对象有两个名称,a(对调用者可见)和 p(在函数中可见)。

后一种情况通常由编译器以与实现指针传递相同的方式实现(但实现细节不是您在形成某物含义的心智模型时应考虑的内容)。