如何“通过引用传递变量”工作?

时间:2015-08-14 04:12:14

标签: c++ pass-by-reference

代码如:

// '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

通过参考案例传递这种不一致的底层机制是什么?

3 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:0)

在您的示例中,a的类型为type,因此bc的类型为type&

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

过去引用有一些差异,但现在主要只是比指针更方便的语法。使用指针,您的示例如下所示:

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);

差异(在现代编译器上)是编译器为您执行引用和解除引用,并且不让指针为空(除非你做了创造性的事情,你将不会这样做)

如果有助于在语言上考虑它,您的功能是说“请给我一个type实例的引用和type实例的副本。”

您的第一个电话是“在这里,获取对此type实例的引用,此处是此另一个type实例的副本。”

你的第二个电话是“在这里,抓住这个对type实例的引用,这里是另一个type实例的副本。”

答案 2 :(得分:0)

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

后:

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(在函数中可见)。

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