'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;
在这两种情况下都有一个变量,它有两个名称,a
和 c
。
因为 C++11 有一个区别,decltype(a)
将引用作为类型的一部分
当您在其后的表达式中使用 a
或 c
时,它指的是该变量。
当你有 void foo(type &p, type q)
(更改名称以避免混淆)时,如果你调用 foo(a, b);
,那么名称 p
将成为参数 a
的另一个名称.一个对象有两个名称,a
(对调用者可见)和 p
(在函数中可见)。
后一种情况通常由编译器以与实现指针传递相同的方式实现(但实现细节不是您在形成某物含义的心智模型时应考虑的内容)。
代码如下:
// '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;
在这两种情况下都有一个变量,它有两个名称,a
和 c
。
因为 C++11 有一个区别,decltype(a)
将引用作为类型的一部分
当您在其后的表达式中使用 a
或 c
时,它指的是该变量。
当你有 void foo(type &p, type q)
(更改名称以避免混淆)时,如果你调用 foo(a, b);
,那么名称 p
将成为参数 a
的另一个名称.一个对象有两个名称,a
(对调用者可见)和 p
(在函数中可见)。
后一种情况通常由编译器以与实现指针传递相同的方式实现(但实现细节不是您在形成某物含义的心智模型时应考虑的内容)。