3

给定以下 c++ 函数:

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

这两种说法有什么区别:

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

一个版本优于另一个版本吗?

4

4 回答 4

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)),即被认为是糟糕的设计。

编辑:我应该补充一点,如果 ReturnAReference() 返回对该函数中本地变量的引用,则该引用将在 ReturnAReference() 返回时立即无效。

于 2013-08-19T02:57:27.257 回答
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将引用一个不再存在的对象,因此将非常量引用绑定到临时对象是非法的。

于 2013-08-19T03:02:27.917 回答
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&,仅仅是因为 anint很小并且复制起来不会很昂贵(它几乎总是适合寄存器)。此外,int&如果引用引用局部变量,则返回值会带来安全问题。对于类或结构,它总是取决于,但是当通过引用或指针返回局部变量时必须小心。

于 2013-08-19T03:28:38.640 回答
0

如果要修改函数引用返回的变量,或者要跟踪对其值的任何更改,请使用 int&。只要您访问它,您就可以确保所引用的变量一直存在。如果您只关心此时引用返回的变量的值,请使用 int.

仅供参考,std::vector 的运算符 [] 和at函数通过引用返回,允许语法如下v.at(0) = 2

于 2013-08-19T03:05:46.650 回答