首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >按值返回是否意味着额外的副本和额外的开销?C++

按值返回是否意味着额外的副本和额外的开销?C++
EN

Stack Overflow用户
提问于 2014-04-21 19:00:28
回答 2查看 627关注 0票数 0

请考虑以下几点:

代码语言:javascript
复制
class Foo { ... };

Foo rbv();

void caller()
{
  Foo x = rbv(); ← the return-value of rbv() goes into x
  ...
}

Foo rbv()
{
  ...
  return Foo(42, 73); ← suppose Foo has a ctor Foo::Foo(int a, int b)
}

将构造多少个Foo类型的对象?

EN

回答 2

Stack Overflow用户

发布于 2014-04-21 19:08:23

也许吧。

在C++11中,如果值具有移动构造函数,则通过移动而不是复制来返回值。这比复制要高效得多。

在某些情况下-例如当返回局部变量或临时变量时(如您在这里所做的)-移动或复制可以被省略。该值被直接创建到调用方的堆栈帧中,因此不需要在返回时移动或复制它。喜欢首字母缩写的人有时称之为(N)RVO -(已命名)返回值优化。

同样,也可以省略从临时返回值到x的复制或移动。

任何优秀的编译器都会实现这种优化,所以你的代码应该只创建一个Foo。您可以通过让析构函数打印一条消息来验证这一点,并观察到它只执行一次:http://ideone.com/xydJqY。如果禁用优化,则最多可能有三个对象。

票数 3
EN

Stack Overflow用户

发布于 2014-04-21 19:03:56

最多可以有两个副本:一个从临时Foo(42, 73)到函数的返回值,另一个从函数的返回值到x。然而,这两个副本都符合复制省略的条件,它允许不制作副本,而是直接在目标中构造对象,相当于Foo x(42, 73);

您可能能够控制编译器利用复制省略的程度;例如,在GCC中,您可以使用-fno-elide-constructors来获取所有两个副本。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23196044

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档