我一直试图理解右值,左值和引用以及它们作为函数(方法)的返回值的用法,因此我为实践目的创建了一些小示例。
因此,首先,我想出了这段代码(在某个地方(可能在这里阅读之后),每当我为某个方法拥有“常规”(无参考)返回值时,它就被认为是右值,当我添加参考运算符登录返回值,如本例所示:
#include <iostream>
int x = 5;
int& References()
{
return x;
}
int main()
{
References() = 3;
std::cout << x;
getchar();
getchar();
}
因此,在这里,函数引用在调用时返回左值,并且此代码工作得很好,但是,由于这种方法有效,我认为我可以做其他类似的事情,这就是我尝试过的事情:
#include <iostream>
int x = 5;
int References()
{
return x;
}
int main()
{
int a = References();
std::cout << a;
getchar();
getchar();
}
此代码工作正常,输出为5,这意味着我已成功为变量a分配了值,这是我期望的,因为此函数返回“普通”整数,因此它是rvalue。
但是, 当我再次向函数References的返回值添加引用运算符时,它再次正常工作:
#include <iostream>
int x = 5;
int& References()
{
return x;
}
int main()
{
int a = References();
std::cout << a;
getchar();
getchar();
}
因此,即使我的函数现在返回以{{value}}形式返回的int&
,此代码仍然有效,并且输出仍然为5,这意味着我设法将值成功分配给变量a。这里发生了什么?任何帮助表示赞赏!
答案 0 :(得分:2)
当您在表达式或赋值中使用引用时,它会评估该引用所引用的内容,而不是内存地址,我想这就是您希望看到的内容。
比较以下函数的输出:
int x = 5;
int& References()
{
return x;
}
int *Pointer()
{
return &x;
}
int main()
{
std::cout << References() << std::endl;
std::cout << Pointer() << std::endl;
return 0;
}
答案 1 :(得分:2)
按引用返回时,您有一个lvalue
;按值返回时,您有一个prvalue
。就您而言,您可以从两者中读取差异,但无法指定给prvalue
,不清楚您的困惑来自何处:
int i1 = lvalue; // fine
int i2 = prvalue; // fine
但是:
lvalue = 123; // fine
prvalue = 123; // error
更接近您的情况:
int &func1();
int func2();
int i1 = func1(); // fine
int i2 = func2(); // fine
func1() = 123; // fine
func2() = 123; // error
更多信息:Value Category
答案 2 :(得分:1)
根据https://docs.microsoft.com/en-us/previous-versions/f90831hc(v=vs.140):
You can think of an lvalue as an object that has a name. All variables, including nonmodifiable (const) variables, are lvalues. An rvalue is a temporary value that does not persist beyond the expression that uses it.
第三个示例与第二个示例完全相同,只是复制值。您可以从左值复制值,就像从右值复制值一样。如果您的变量的类型为int&,则您不会复制实际值,您将获得相同的引用。这可以帮助您了解:
#include <iostream>
int x = 5;
int& References()
{
return x;
}
int main()
{
int a = References();
int& b = References();
std::cout << a; // 5
std::cout << b; // 5
std::cout << x; // 5
a = 6;
b = 7;
std::cout << a; // 6
std::cout << b; // 7
std::cout << b; // 7
getchar();
getchar();
}
答案 3 :(得分:1)
为进行比较:
int n = 10;
int& r = n;
int* p = &n;
int x = n; // copy by value
int y = r; // copy by value, too, use the variable referenced as source
int z = *p; // copy by value third time, using variable pointed to
int& r0 = r; // copy the reference, i. e. r0 now references n as well
int* p0 = p; // copy the pointer...
n = 12;
// now x, y, z all STILL have value 10!
// r, r0, *p and *p0, in contrast, all yield 12
功能相同:
int& ref() { return n; }
int val() { return n; }
int& r1 = ref(); // copy the reference, again r1 references n!
int& r2 = val(); // INVALID!!!
// the latter is comparable to:
int& r3 = 7; // invalid...