关于在C ++中返回引用的函数的问题

时间:2010-09-01 17:45:03

标签: c++ reference

从函数返回对局部变量的引用是否可以?通过本地,我的意思是变量将在函数内创建(在堆栈上,即不使用new),并且其范围仅在该函数内。当我搜索这个时,我得到了相互矛盾的答案。 1)说这种用法是正确的,但2)与之相矛盾。

1)http://functionx.com/cpp/examples/returnreference.htm
2)http://www.cprogramming.com/tutorial/references.html(在参考文献和安全部分下)

哪一个是对的?

我遇到的另一个问题是,如果1)是正确的,那么以下是相同的目的。

i)int& a = func();
ii)int a = func();其中func()返回对int的引用(该函数中的局部变量)。

在上述两种情况下,都没有复制涉及的返回值。我想防止复制返回值,因为返回值可能很大。

提前谢谢。

Raghava。

6 个答案:

答案 0 :(得分:6)

您可以在函数中返回对静态局部变量的引用。否则,它是一个灾难的处方,因为一旦函数返回,局部变量就会被销毁。

Following可能会有所帮助,它采用您在第一次参考中引用的相同示例。

编辑2:

对于帖子中的第ii点,让我们假设一个函数'fn'如图所示

int& fn(){
static int x;
return x;
}

int a = fn();

这涉及来自表达式'fn'的左值的副本。

如果是

,则不涉及副本
int &a = fn();

答案 1 :(得分:6)

正如其他人所说,不要这样做。返回引用或指向局部变量的指针总是错误的,因为返回的行为会删除局部变量,因此引用或指针会自动失效。

复制可能不是问题。从函数返回时,允许C ++编译器跳过复制构造函数(“返回值优化”),因此足够智能的编译器可能能够构建适当的值。因此,您可以在不进行任何复制的情况下返回较大的值。试试看吧;你可以暂时将输出语句放在复制构造函数中(如果你已经编写了一个并且没有使用自动生成的语句)来查看它是否实际被调用。

因此,如果没有运行和尝试,您不知道是否有实际的复制正在进行,如果是,那么它有多大的问题。与往常一样,时间和概况运行以查看是否存在问题,如果存在问题,请在何处进行。在计时和分析之前,做任何冒险和/或混乱以加速性能的事情几乎都不值得。

答案 2 :(得分:5)

如果你的意思是函数内部的一个变量,没有......返回对它的引用总是无意义的。从成员函数返回对成员变量的引用是完全没问题的。

希望避免复制大型数据结构。请等到你有实际的个人资料数据显示你是a)实际制作副本,b)它实际上是一个瓶颈。 “过早优化是所有邪恶的根源”,可能有点极端,但过早优化肯定会导致很多痛苦和麻烦,而很少,如果有的话,实际上提供了这些尝试所要达到的任何好处。

答案 3 :(得分:4)

您在第一个链接中看到的示例完全是假的。 functionx.com上的那个页面很垃圾。返回对本地(自动)变量的引用始终是错误,因为任何访问返回值的尝试都将导致未定义的行为。

第二个链接正确。

答案 4 :(得分:2)

永远不能从函数返回对非静态局部变量的引用。当函数返回时,变量超出范围,因此引用将引用被破坏的对象。

虽然在1)中提供的第一个示例中这似乎可以“正常工作”,但这种不良做法很快就会因为具有析构函数或更大的类而失败。

最好返回指针,返回对本地静态对象的引用,返回对成员变量的引用。

在这种情况下,如果对象是在要返回的函数内构造的,那么您可能会考虑在大类上实现C ++ 0x移动语义。这可能会将“大型副本”变成几个指针交换。

答案 5 :(得分:0)

假设func返回对函数返回后生成的值的引用(静态本地或全局),那么

i) int& a = func();
ii) int a = func(); where func() returns a reference to an int (local variable in that function).

完全不同

in(i)a仍指静态或全局。 Chaning a将改变原始变量

在(ii)中a是本地副本,更改它对原始变量没有影响