C++ 如何';通过引用传递变量';工作
代码如下:C++ 如何';通过引用传递变量';工作,c++,pass-by-reference,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的第一个参数是类型&,它是一个引用,foo(c,b)在我看来比foo(a,b)更一致,因为c本身是一个引用类
// '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
的第一个参数是类型&
,它是一个引用,foo(c,b)
在我看来比foo(a,b)
更一致,因为c
本身是一个引用类型&
但a
只是一个类型
变量
例如说voidbar(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
属于类型&
当您通过传递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 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&c=a代码>,那么您为什么希望键入&a=a代码>在函数声明中不起作用?@user657267type&a=a
-what?@mattmcnab我想说的是,如果将函数参数视为另一个局部变量声明,那么很明显这是为什么,OP清楚地理解type&c=a代码>起作用,将下面声明的foo
与foo
的参数a
绑定也一样。引用不是内存地址。引用可能根本不需要存储(请参见[dcl.ref]/4)。引用是对象的另一个名称。这可能是标准语言在中的定义方式,但在大多数常用的编译器中,它通常作为指针实现。