我一直以为像这样的签名
int& val() {...}
将向调用者指示返回对已存在的 int 值的引用。但是,如果我使用该函数并将其分配给int
变量(而不是int&
),它就会编译。然而,结果是函数实际返回值的副本 - 如打印地址所示,如以下会话中所示:
#include <iostream>
using namespace std;
int v = 8;
int& vref()
{
return v;
}
int main()
{
/*declared type of x does not match the return type! However, no warnings/messages about any implicit conversion are given here*/
int x = vref();
int& y = vref(); // correct type
// Now I declare pointers to x,y and v and display their addresses
int* ptr_x = &x;
int* ptr_y = &y;
int* ptr_v = &v;
cout << "Addr of x: " << ptr_x << endl;
cout << "Addr of y: " << ptr_y << endl;
cout << "Addr of v: " << ptr_v << endl;
}
导致y
并v
驻留在相同的内存位置(这是我所期望的) - 但不是x
. 所以,我想知道分配时幕后发生了什么int x = vref();
和
您复制原始值,并将其存储到唯一且不同的变量中
x
。另一方面,与:
您将获得对原始变量的引用
v
。该变量y
可以被视为的别名v
。任何时候你使用y
你实际上是在使用v
.因为该
vref()
函数返回的别名v
,所以 的定义和初始化x
实际上相当于:和
x
都是v
相同的类型,因此不进行类型转换。这种等价当然是相同的,其
y
等价于:请注意,第一个“问题”是复制返回值,这就是返回常量值实际上没有用的原因。
即使是对常量(即 )的引用
int const&
仍然可以复制其值。不同之处在于,如果您修改副本(如
x
示例中的变量),您只会修改副本本身,而不是原始值。因此,eg
x++
将增加 的值,x
但保持v
不变。但y++
会增加价值v
。vref
返回对 的引用v
。引用不能反弹。从 返回的引用vref
将始终引用v
。使用该引用初始化另一个引用会使该另一个引用引用v
。然而,这
复制
v
来初始化x
.x
不是参考。x
和v
是两个不同的整数。完全正确。
vref
返回引用并不矛盾。