我理解C ++中引用的概念,并且我理解它们在函数参数中使用时的作用,但我仍然对它们如何使用返回类型感到困惑。
例如,在参数中使用时,此代码:
int main (void) {
int foo = 42;
doit(foo);
}
void doit (int& value) {
value = 24;
}
与此代码类似:
int main (void) {
int foo = 42;
doit(&foo);
}
void doit (int* value) {
*value = 24;
}
(知道每次在 doit 的第一个代码示例中使用时,编译器会自动在 value 前面加上一个星号,但在后者中你是'每次尝试使用 value )
时,都必须将星号放在自己的位置因此,当用作参考时,下一个代码(使用返回类型中的引用)转换为什么?它是否返回指向int的指针?或者只是返回一个int?
int main (void) {
int* foo = /*insert useful place in memory*/;
foo = doit(foo);
}
int& doit (int* value) {
//insert useful code
}
答案 0 :(得分:13)
这意味着您通过引用返回,至少在这种情况下,可能不需要。它基本上意味着返回的值是从函数返回的任何内容的别名。除非它是一个持久的对象,否则它是非法的。
例如:
int& foo () {
static int x = 0;
return x;
}
//...
int main()
{
foo() = 2;
cout << foo();
}
合法且打印出2
,因为foo() = 2
会修改foo
返回的实际值。
然而:
int& doit () {
int x = 0;
return x;
}
将是非法的(好吧,访问返回的值),因为x
在方法退出时被销毁,所以你将留下悬空引用。
通过引用返回对于自由函数并不常见,但它适用于返回成员的方法。例如,在std
中,公共容器的operator []
按引用返回。例如,使用[i]
访问向量的元素会返回对该元素的实际引用,因此v[i] = x
实际上会更改该元素。
另外,我希望“基本上与此代码相同”意味着它们在语义上类似(但不是真的)相似。没什么。
答案 1 :(得分:3)
这意味着您返回指向对应数据所在的内存地址的指针,而不是非常数据。
答案 2 :(得分:1)
假设这段代码(使其与第一个例子相当):
int main (void) {
int* foo = /*insert useful place in memory*/;
*foo = doit(foo);
}
int& doit (int* value) {
*value = 24;
return *value;
}
int&
在这种情况下作为返回类型并不是很有用,因为它提供了对内存中变量的访问(将指针传递给函数)。
它是否返回指向int的指针?或者只是返回一个int?
不,它返回对int的引用。如果需要,可以将其视为不能为nullptr
的指针。
答案 3 :(得分:0)
嗯,知道答案的最好方法是试试......
您的代码不会传递类型检查,因为当您接受返回值作为int的指针时,doit将返回int的引用。
你可以看看这个:
#include<iostream>
using namespace std;
int& doit (int* value) {
value[0] = 3;
return value[4];
}
int main (void) {
int* foo = new int[10];
for (int i=0; i<10; i++)
foo[i] = i;
int& bar = doit(foo);
cout<<bar<<endl;
for (int i=0; i<10; i++)
cout<<foo[i]<<" ";
cout<<endl;
bar = 12;
for (int i=0; i<10; i++)
cout<<foo[i]<<" ";
cout<<endl;
return 0;
}
变量“bar”将接受返回值,并且可以使用它来更改“foo”的内容。正如Luchian所提到的,从函数返回引用可能很危险,因为后面的代码可能会修改堆栈中的值。