临时变量 与 Named Return Value (NRV) optimization



返回值如何实现?

【实现模型1】cfont的实现采用了双阶段转化。1.首先声明一个额外的参数,类型上类对象的引用,用来存放返回结果。2.对这个参数利用返回值进行拷贝初始化。过程类似于参数传递,也是要定义一个临时对象,用来保存返回值,然后在函数内部调用拷贝构造函数用那个return值进行初始化。

X bar()

{

X xx;

// process xx ...

return xx;

}

编译器转化后

// 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】Named Return Value (NRV) optimization,具名返回值优化,实现这种优化有个前提,就是必须提供copy constructor,因为NRV优化的目的就是为了剔除copy constructor的使用。只有有了才能被剔除,否则谈不上剔除。一般的如果不优化NRV,其实现就是类似于模型1中的过程,而实现了优化的过程则上这样的。

X bar()

{

X xx;

// ... process xx

return xx;

}

__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;

}

是否需要拷贝构造函数呢?

【注意】一方面要考虑默认的语义是否符合我们的需要。另一方面如果对象面临大量的拷贝操作,有必要实现一个拷贝构造函数以支持NRV优化。但是如果想使用底层的memcpy之类的直接进行bit wise copy,注意是否真的是bit wise copy拷贝,比如如果是virtual,这样可能破坏调vptr。

测试:VS 2008

class X{
public:
X(){cout<<"X::X()\n";}
X(const X& ){cout<<"X::X(const X& )\n";}
X& operator=(const X& ){cout<<"X::operator=(const X& )\n";return *this;}
};

X Foo(){ return X();}

X Goo(){ X x; return x;}

int _tmain(int argc, _TCHAR* argv[])
{

Foo()
//X::X()

Goo()
//X::X()
//X::X(const X&) 临时变量

X x;
//X::X()
x = Foo();
//X::X()
//X::operator=(const X& )

X y = Foo();
//X::X()

X z;
//X::X()
z = Goo();
//X::X()
//X::X(const X& ) 临时变量
//X::operator=(const X& )

X w = Goo();
//X::X()
//X::X(const X& ) 临时变量

return 0;
}
posted @ 2009-11-09 02:58  史莱姆  阅读(405)  评论(0编辑  收藏  举报