返回本地人是否也涉及创建返回的临时工?
Does returning a local also involve creating a temp for return?
我来自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/NRVO
和copy elision
,则有一个Employee(int)
调用和两个copy c-tor
调用,一个在返回时,一个在构造myEmp
时。使用RVO
和copy elision
- 一次调用Employee(int)
,可能零次调用复制 c-tor。
第二次调用没有copy elision
的复制构造函数是强制性的,因为您想从另一个对象构造新对象(工作到copy c-tor
)。
函数返回的语义与你无关 处理返回值:返回值被复制到某个位置 当本地堆栈帧被破坏时,它不会消失。 所以没有 RVO,在您的示例中,您有:
-
在堆栈帧中构造一个名为
local
的局部变量 的getEmp
. -
将返回对象的构造复制到调用方的某个位置 将能够访问。 通常,调用方为 在其自己的堆栈帧中返回对象,并传递隐藏参数 将此内存的地址发送到被调用的函数。 RVO 或 NRVO 允许编译器将此返回的对象"别名"到本地对象:在 您的情况,
local
在作为 隐藏参数,而不是在本地堆栈帧中。
返回 后,返回的对象将被"使用",然后在 完整表达式的结尾。如果此用途是初始化本地 变量使用复制构造函数,中间值可以是 被省略;编译器将传递实际对象的地址 构造为被调用函数的隐藏参数。 (严格 说起来,这不是NRVO,但它是相关的。 然而,其他用途, 不能省略;如果返回值用于赋值 现有变量,例如赋值运算符将需要 对要分配的实例的引用。 正式要求 中间对象之所以存在,是因为返回值的大多数用法是 不作为复制构造函数的参数。
最后,考虑到现代编译器技术,您可能可以依靠 编译器系统地省略了上面的第二个副本。 第一个副本 (RVO或NRVO)可能更困难一些。 我希望看到它 系统地在上述简单情况下:RVO 任何时候都有 临时的单次返回,以及NRVO随时有一次返回 它返回在 功能。 NRVO(实际上也是RVO,尽管我不知道为什么) 如果函数中有多个返回值,则不太可能发生。
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- 什么时候在C++中返回常量引用是个好主意
- 你能重载对象变量名本身返回的内容吗
- 为什么 Serial.println(<char[]>);返回随机字符?
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 如何获取std::result_of函数的返回类型
- QueryWorkingSet总是返回false
- (C++)分析树以计算返回错误值的简单算术表达式
- 访问者访问变体并返回不同类型时出错
- 如何返回一个类的两个对象相加的结果
- OpenInventor从9.8升级到10.4.2后,GLSL纹理返回零
- lower_bound()返回最后一个元素
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- 奇怪的(对我来说)返回声明 - 在谷歌上找不到任何关于它的信息
- 如何取消对nullptr的屏蔽,返回正确的对象
- 奇怪的结构&GCC&clang(void*返回类型)
- 架构决策:返回std::future还是提供回调
- 从python中调用C++函数并获取返回值
- 矩阵向量乘法(cublasDgemv)返回零
- 返回本地人是否也涉及创建返回的临时工?