在C ++中初始化引用和变量

时间:2013-08-19 02:47:51

标签: c++

给出以下c ++函数:

int& ReturnAReference() {
   /* Do something here */
}

这两个陈述之间是否有任何区别:

int normalVariable = ReturnAReference();
int& referenceVariable = ReturnAReferene();

一个版本比另一个版本更受欢迎吗?

4 个答案:

答案 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等语法。