C++函数返回引用

21

为什么我不能/不应该将对本地变量的引用返回给函数?这是因为在函数执行完后,临时变量会自动销毁吗?

const string & wrap(string & s1, const string & s2){
    string temp;
    temp = s2 + s1 + s2;
    return temp;
}
这个怎么样?
const string & wrap2(const string & s1, const string & s2){
    return (s2 + s1 + s2);  
}

13
好的,大致就是这样。 - Blair Conrad
还有一个函数我需要澄清。请看编辑。 - Pwnna
你的第二个函数只是第一个函数的简写形式(编译器可能会优化成第二种形式),因此仍然是错误的。你需要返回一个 std::string。 - Christian Rau
2
第二个问题取决于operator+的实现方式,但假设通常的设置是相同的。在这种情况下,对临时变量和本地变量的引用是相同的。两者都会消失。 - Dennis Zickefoose
我正在学习C++。我正在从Python转移技能,这两者有很大的不同。我想确保我不会犯一些错误,这些错误将无法通过理解所有概念来调试。 - Pwnna
显示剩余2条评论
4个回答

10

函数内声明的变量是在堆栈上分配的。当函数返回给调用者时,用于存储变量的堆栈空间被回收并且不再可用,之前存在的变量也不存在了(虽然实际上它们还在,但你不能使用它们,并且它们随时可能被覆盖)。所以,基本上你说的没错。


如果函数属于一个类并返回其包含的对象的引用,该怎么办? - locke14
如果对象在方法之外被声明,则它不会被销毁。@locke14 - TomeeNS

7

就是这样。当局部变量超出其作用域时,它会消失并被销毁。如果你返回对它的引用或指针,那么这个引用或指针将指向垃圾,因为对象不再存在。


4

"这个怎么样: ..."

s2 + s1 + s2本身是一个临时局部变量,因此它也无法通过引用返回。

你可以做的事情 - 但请不要这样做,这会导致内存泄漏! - 是

const string & wrap2(const string & s1, const string & s2){
  string *pt = new string(s2+s1+s2);
  return *pt;
}

这会创建一个全局有效的字符串,因此可以传递引用,因为它在函数执行后不会被销毁。实际上,它永远不会被销毁,并且将占用空间,只要程序运行:您可能不希望这样做!
如果它不是一个const引用,您可以手动delete它。 编辑:所以事实证明,您甚至可以删除const引用,但是再次这样做并不好。

1
你仍然可以手动删除它。例如,这个编译没有问题http://ideone.com/dcUg3。然而,我认为这仍然是一个不好的做法。返回引用具有隐含的意义,即其他东西正在控制对象的生命周期。 - Michael Anderson
1
确实。我不知道这一点 - 似乎有点奇怪,你可以在不允许更改的情况下删除某些内容。 - leftaroundabout

1
就像之前的帖子所说,这是因为本地变量最终会在堆栈上结束。那个物理内存可能会被分配给另一个函数框架并更改,而您的指针仍然挂在同一位置(现在已更改)。我不确定,但我认为它不是“销毁”,但它肯定没有受到任何未来堆栈分配更改的保护。

2
“string temp” 被销毁。当函数返回时,它的析构函数被调用。 - TonyK

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接