您的位置:首页 > 产品设计 > UI/UE

Named Return Value Optimization

2016-03-24 13:04 351 查看
  已知下列函数定义:

X bar() {
X xx;
// process xx ...
return xx;
}


  你可能会问bar()的返回值如何从局部对象xx中拷贝过来?

实现模型1

返回值的初始化(Return Value Initialization)

  Stroustrup在cfront中的解决做法是一个双阶段转化:

首先加上一个额外参数,参数类型是对对象的引用,用来存放返回结果;

在return指令之前安插一个copy constructor调用操作,对这个参数利用返回值进行拷贝初始化。

  根据上述算法,bar()的转换如下:

// function transformation to reflect
// application of copy constructor
// Pseudo C++ Code
void bar( X& __result )
{
X xx;

// compiler generated invocation

// of default constructor

xx.X::X();

// ... process xx

// compiler generated invocation

// of copy constructor

__result.X::X( xx );

return;

}


实现模型2

在编译器层面做优化(Optimization at the Compiler Level)

  Named Return Value (NRV) optimization,具名返回值优化。

  在一个像bar()这样的函数中,所有的return指令传回相同的具名数值,因此编译器有可能自己做优化,方法是:以result参数取代named return value。

  根据这个方法,bar()的转换如下:

//__result is substituted for xx by the compiler:
void bar( X &__result )
{

// default constructor invocation

// Pseudo C++ Code

__result.X::X();

// ... process in __result directly

return;

}


Named Return value 优化:

  NRV优化的本质是优化掉拷贝构造函数。在实现模型1中我们看到了,返回对象的实现总是先对某个对象进行操作,操作完成后,使用Copy Constructor将操作后的对象内容复制到另外一个对象中,然后返回。 基于这样一个前提,NRV可以调用Copy Constructor这一步被省掉。所以NRV的前提必须要有Copy Constructor。

  NRV也有副作用,就是Copy Constructor中的代码不会被执行。

【注意】一方面要考虑默认的语义是否符合我们的需要。另一方面如果对象面临大量的拷贝操作[ 比如这个class的object需要经常以传值的方式返回],有必要实现一个拷贝构造函数以支持NRV优化。但是如果想使用底层的memcpy之类的直接进行bit wise copy,注意是否真的是bit wise copy拷贝,比如如果是virtual,这样可能破坏调vptr。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  NRV