返回本地人是否也涉及创建返回的临时工?

Does returning a local also involve creating a temp for return?

本文关键字:返回 临时工 创建 本地人 是否      更新时间:2023-10-16

我来自Java,那里的任何东西都是引用的,所以我试图弄清楚c ++实例创建的基本原理。

Employee getEmp(int a) {
Employee local(a);
return local;
}
Employee myEmp = m.getEmp(10);

有 3 次员工实例化(没有 RVO)是否正确?
1 - 创建本地副本
2 - 创建临时以绑定到引用)
3 - 创建 myEmp

为什么在步骤 2 中有需要?为什么不直接将本地复制到 myEmp?

如果我只使用 Ubuntu,我应该依靠 RVO 吗,我是否正确,使用 RVO 只完成了两个实例创建(步骤 2 中不需要)?

谢谢!!!

如果没有RVO/NRVOcopy elision,则有一个Employee(int)调用和两个copy c-tor调用,一个在返回时,一个在构造myEmp时。使用RVOcopy elision- 一次调用Employee(int),可能零次调用复制 c-tor。

第二次调用没有copy elision的复制构造函数是强制性的,因为您想从另一个对象构造新对象(工作到copy c-tor)。

函数返回的语义与你无关 处理返回值:返回值被复制到某个位置 当本地堆栈帧被破坏时,它不会消失。 所以没有 RVO,在您的示例中,您有:

  1. 在堆栈帧中构造一个名为local的局部变量 的getEmp.

  2. 将返回对象的构造复制到调用方的某个位置 将能够访问。 通常,调用方为 在其自己的堆栈帧中返回对象,并传递隐藏参数 将此内存的地址发送到被调用的函数。 RVO 或 NRVO 允许编译器将此返回的对象"别名"到本地对象:在 您的情况,local在作为 隐藏参数,而不是在本地堆栈帧中。

  3. 返回
  4. 后,返回的对象将被"使用",然后在 完整表达式的结尾。如果此用途是初始化本地 变量使用复制构造函数,中间值可以是 被省略;编译器将传递实际对象的地址 构造为被调用函数的隐藏参数。 (严格 说起来,这不是NRVO,但它是相关的。 然而,其他用途, 不能省略;如果返回值用于赋值 现有变量,例如赋值运算符将需要 对要分配的实例的引用。 正式要求 中间对象之所以存在,是因为返回值的大多数用法是 不作为复制构造函数的参数。

最后,考虑到现代编译器技术,您可能可以依靠 编译器系统地省略了上面的第二个副本。 第一个副本 (RVO或NRVO)可能更困难一些。 我希望看到它 系统地在上述简单情况下:RVO 任何时候都有 临时的单次返回,以及NRVO随时有一次返回 它返回在 功能。 NRVO(实际上也是RVO,尽管我不知道为什么) 如果函数中有多个返回值,则不太可能发生。