C ++返回对局部变量的引用 [英] C++ Returning reference to local variable

查看:111
本文介绍了C ++返回对局部变量的引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果必须返回i,以下代码(func1())是否正确?我记得在某处读到返回对局部变量的引用时出现问题。它和func2()有什么不同?

Is the following code (func1()) correct if it has to return i? I remember reading somewhere that there is a problem when returning reference to a local variable. How is it different from func2()?

int& func1()
{
    int i;
    i = 1;
    return i;
}

int* func2()
{
    int* p;
    p = new int;
    *p = 1;
    return p;
}


推荐答案

p>

This code snippet:

int& func1()
{
    int i;
    i = 1;
    return i;
}

无法工作,因为您要将别名对象的生命周期限于函数调用的范围。这意味着一旦 func1()返回, int i 死,使从函数返回的引用无价值,因为它现在指到不存在的对象。

will not work because you're returning an alias (a reference) to an object with a lifetime limited to the scope of the function call. That means once func1() returns, int i dies, making the reference returned from the function worthless because it now refers to an object that doesn't exist.

int main()
{
    int& p = func1();
    /* p is garbage */
}

因为变量分配在自由存储上,而不是绑定到函数调用的生命周期。但是,您负责删除分配的 int

The second version does work because the variable is allocated on the free store, which is not bound to the lifetime of the function call. However, you are responsible for deleteing the allocated int.

int* func2()
{
    int* p;
    p = new int;
    *p = 1;
    return p;
}

int main()
{
    int* p = func2();
    /* pointee still exists */
    delete p; // get rid of it
}

通常你会将指针包装在 RAII 类和/或工厂函数,因此您不必 delete

Typically you would wrap the pointer in some RAII class and/or a factory function so you don't have to delete it yourself.

在任何一种情况下,你都可以返回值本身(虽然我意识到你提供的例子可能是假设的):

In either case, you can just return the value itself (although I realize the example you provided was probably contrived):

int func3()
{
    return 1;
}

int main()
{
    int v = func3();
    // do whatever you want with the returned value
}

以相同的方式返回大对象是完全正确的 func3()返回原始值,因为现在每个编译器实现某种形式的返回价值优化

Note that it's perfectly fine to return big objects the same way func3() returns primitive values because just about every compiler nowadays implements some form of return value optimization:

class big_object 
{ 
public:
    big_object(/* constructor arguments */);
    ~big_object();
    big_object(const big_object& rhs);
    big_object& operator=(const big_object& rhs);
    /* public methods */
private:
    /* data members */
};

big_object func4()
{
    return big_object(/* constructor arguments */);
}

int main()
{
     // no copy is actually made, if your compiler supports RVO
    big_object o = func4();    
}

有趣的是,将一个临时数据绑定到一个 const 完美合法的C ++ 。 p>

Interestingly, binding a temporary to a const reference is perfectly legal C++.

int main()
{
    // This works! The returned temporary will last as long as the reference exists
    const big_object& o = func4();    
    // This does *not* work! It's not legal C++ because reference is not const.
    // big_object& o = func4();  
}

这篇关于C ++返回对局部变量的引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆