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

查看:41
本文介绍了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;
}

推荐答案

这段代码:

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 类和/或工厂函数中,以便您不必自己删除.

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++.

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天全站免登陆