我一直以为签名像
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();
vref
返回对 v
的引用。引用不能反弹。从 vref
返回的引用将始终引用 v
。使用该引用初始化另一个引用使得另一个引用引用 v
。
然而,
int x = vref();
复制
v
以初始化 x
。 x
不是参考。 x
和 v
是两个不同的整数。
但是,如果我使用该函数并将其分配给 int 变量(而不是 int&),它就会编译。然而,结果是函数实际返回值的副本 - 如打印地址所示,如以下会话中所示:
完全正确。
与
vref
返回引用并不矛盾。
与
int x = vref();
您制作原始值的副本,并将其存储到唯一且不同的变量
x
中。
另一方面,与:
int& y = vref();
您将获得对原始
v
变量的引用。变量 y
可以看作 v
的 alias。任何时候您使用
y
,您实际上都在使用 v
。
请注意,第一个“问题”,即复制返回值,这就是返回常量值实际上没有用的原因。
即使是对常量的引用(即
int const&
)仍然可以复制其值。
不同之处在于,如果您修改副本(如示例中的变量
x
),您只会修改副本本身,而不是原始值。
所以例如
x++
将增加 x
的值,但保持 v
不变。但y++
会增加v
的价值。