C++ 将函数的返回值存储在参考C++;

C++ 将函数的返回值存储在参考C++;,c++,reference,return-value,C++,Reference,Return Value,将对象的返回值存储在引用中是否有效 class A { ... }; A myFunction() { A myObject; return myObject; } //myObject goes out of scope here void mySecondFunction() { A& mySecondObject = myFunction(); } 是否可以这样做以避免将myObject复制到mySecondObject?不再需要myObject,它应该

将对象的返回值存储在引用中是否有效

class A { ... };
A myFunction()
{
    A myObject;
    return myObject;
} //myObject goes out of scope here

void mySecondFunction()
{
    A& mySecondObject = myFunction();
}
是否可以这样做以避免将myObject复制到mySecondObject?不再需要myObject,它应该与mySecondObject完全相同,因此理论上,将对象的所有权从一个对象传递到另一个对象会更快。(这也可以使用boost共享指针,但其开销与共享指针相同。)


提前感谢。

不允许将临时引用绑定到非常量引用,但如果将引用设置为常量,则会将临时引用的生存期延长到引用,请参阅

简言之:

const A& mySecondObject = myFunction();

使用常量引用是可能的

myFunction
按值返回,因此返回值是一个临时对象。可以将临时对象绑定到常量引用,临时对象的生存期将延长到引用的生存期。很遗憾,您不能将临时引用绑定到非常量引用

myFunction
的返回值可能是
myObject
的副本。另一方面,复制构造函数省略(在本例中称为“命名返回值优化”)允许编译器将
myObject
直接构造到临时对象中,该临时对象是
myFunction
的返回值,可能位于调用代码堆栈的某个位置。如果它这样做,那么当
myObject
超出范围时,对象实际上并没有被销毁。通常会实施优化-例如,GCC(通常?)甚至在没有任何优化标志的情况下也会实施优化

复制省略还允许编译器避免所有复制,前提是:

A mySecondObject = myFunction();

这需要应用两种合法类型的复制省略:(1)从函数返回命名值,以及(2)从临时对象初始化对象。

您可能对许多编译器为避免调用复制构造函数而采用的方法感兴趣。

您知道为什么不允许这样做吗?我不确定,但我猜原因是允许非常量引用意味着编译器需要确定引用被重新分配。我认为这通常被认为是动态范围分析的一部分,而不用于C++标准。另一方面,在const情况下,只需要确定引用的静态生存期。这种分析在其他情况下可能已经需要,因此被认为是可以接受的。我们还可以注意到,这是一种非常简单的指针跟踪功能,我们可以想象一个更先进的系统。但一般来说,我认为C++希望避免这个问题,而将它委托给程序员。这就是智能指针的作用。你的链接断了。我找到了另一个,但它看起来不完整。@renadeen的链接现在也死了,但你可以在上面找到它。这是我正在寻找的想法之一。我无法访问该页面,但我相信会类似。在“…对const的值引用和左值引用延长了临时对象的生存时间…”的底部,然后引用,作为例外列出,“…在return语句中临时绑定到函数的返回值不被扩展…”这是否意味着即使它是常量ref,它也是UB,因为ref引用了函数的返回值?@jrh:不,第二个链接讨论的是,如果在return语句中,将临时值绑定到引用,会发生什么情况。因此,例如
const int&foo(){return int();}
是不好的,因为您获取了对临时
int()
的引用,然后将其绑定到从
foo
返回的引用。这无法延长临时文件的生存期。True。公平地说,临时返回值的行为有理由不同于在堆栈上返回变量。