给出以下c ++函数:
int& ReturnAReference() {
/* Do something here */
}
这两个陈述之间是否有任何区别:
int normalVariable = ReturnAReference();
int& referenceVariable = ReturnAReferene();
一个版本比另一个版本更受欢迎吗?
答案 0 :(得分:9)
关于这个:
int normalVariable = ReturnAReference();
normalVariable
是一个整数,并被赋予ReturnAReference()
引用的int的值。因此,normalVariable
的增量,分配或执行任何其他操作都不会影响ReturnAReference()
内部的任何内容。
关于这个:
int& referenceVariable = ReturnAReference();
referenceVariable
是对整数的引用,否则该整数将在ReturnAReference()
的内部。因此,referenceVariable
的增量,分配或执行任何其他操作会影响ReturnAReference()
内部的任何内容。
首选取决于您要完成的任务,但在许多情况下,第二种方法(使用referenceVariable
)违反了“封装”(http://en.wikipedia.org/wiki/Encapsulation_(object-oriented_programming)),这被认为是设计不佳。< / p>
编辑:我应该补充一点,如果ReturnAReference()返回对该函数中本地变量的引用,那么只要ReturnAReference()返回,该引用就会无效。
答案 1 :(得分:1)
在参考初始化之后,例如通过
int i = 42;
int& r1 = i;
int& r2 = ReturnAReference();
int& r3(i);
int& r4{i}; // C++11
int& r5 = {i}; // C++11
它成为别名,即其初始化对象的另一个名称。 不是另一个整数。 请注意,在C ++标准的语言中,对象只是一个存储区域,不一定是类的实例。
作为参考是一个别名,如果你使用引用操作,你将在原始对象上运行 (它已被初始化的那个):
int i = 42;
int& r = i;
// r is now an alias for i, both refer to the same object
r = 21; // a true assignment
std::cout << i; // will print 21
声明
int normalVariable = ReturnAReference();
引入了int
类型的新对象以及该对象的名称:normalVariable
。此对象使用ReturnAReference()
返回的对象进行初始化,这意味着返回的对象的值将复制到名为normalVariable
的新对象中。
另一方面,声明
int& referenceVariable = ReturnAReferene();
仅为ReturnAReference()
返回的对象引入新名称。
如果您的函数会返回非引用int
,例如int ReturnAnInt();
,则声明
int& r = ReturnAnInt();
将变为非法,因为此函数返回的对象是临时,它只存在此行的末尾(在本例中)。在下一行中,名称r
将引用一个不再存在的对象,因此将非const引用绑定到临时对象是非法的。
答案 2 :(得分:1)
假设您有以下定义:
int test = 4;
int& ReturnAReference() {
return test;
}
1)两个陈述之间是否有任何区别:
int normalVariable = ReturnAReference();
在这种情况下,normalVariable
将保留返回值的副本(不是引用),因为赋值运算符将返回值引用的值复制到normalVariable
。这意味着在
normalVariable = 1;
normalVariable
现在为1,但test
仍为4.
但是,如果你有写作
int& referenceVariable = ReturnAReferene();
并做
normalVariable = 1;
normalVariable
现在为1,test
也为1,因为normalVariable
只是test
的别名。
返回参考时要小心。例如,如果你要做
int& ReturnAReference() {
int i = 0;
return i;
}
从ReturnAReference()
返回的引用将不再有效,因为它仅在函数内部有效并且在退出时将被销毁。
2)一个版本比另一个版本更受欢迎吗?
对于整数或其他原始类型,我希望int
返回值超过int&
,因为int
很小并且复制起来不会很昂贵(它几乎总是适合寄存器)。此外,如果引用引用局部变量,则int&
返回值会引发安全问题。对于类或结构,它总是取决于,但是在通过引用或指针返回局部变量时必须小心。
答案 3 :(得分:0)
如果要修改函数引用返回的变量,或者要跟踪其值的任何更改,请使用int&amp ;.只要您访问它,就可以确保您引用的变量存在。如果您只关心该点引用返回的变量的值,请使用int。
FYI,std :: vector的operator []和at
函数按引用返回,允许使用以下v.at(0) = 2
等语法。