c++ - 在 C++ 中返回对局部变量的引用

标签 c++

如果必须返回 i,下面的代码 (func1()) 是否正确?我记得在某处读到,返回对局部变量的引用时会出现问题。它与 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 就会死亡,使从函数返回的引用变得毫无值(value),因为它现在引用了一个不存在的对象。

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

第二个版本确实有效,因为变量是在自由存储上分配的,不受函数调用生命周期的限制。但是,您有责任删除分配的 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 中类和/或工厂函数,因此您不必自己删除它。

无论哪种情况,您都可以直接返回值本身(尽管我意识到您提供的示例可能是人为设计的):

int func3()
{
    return 1;
}

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

请注意,以 func3() 返回原始值的方式返回大对象是完全没问题的,因为现在几乎每个编译器都实现了某种形式的 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();    
}

有趣的是,将一个临时变量绑定(bind)到一个const 引用是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++ - 在 C++ 中返回对局部变量的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42143869/

相关文章:

c++ - 对于小于max_size的大小,无法创建大于max_size()的std::vector

c++ - 根据模板参数大小在成员函数中使用不同的返回类型

c++ - 接近矩形的轮廓

c++ - 如何从数组中向后读取十六进制字符并转换为 int

c++ - 派生到基隐式指针类型转换

c++ - Visual Studio 生成的二进制文件

c++ - 如何为函数指针设置函数属性?

c++ - WinCE6 上的 QTcpServer->listen() "protocol type not supported"

c++ - 找到第二个最小值

c++ - 删除共享指针