在visual c++ 2005和较前版本中,似乎都不支持《深入探索c++对象模型》中所说的:“用户是否定义copy structor(复制构建)决定是否打开NRV优化”,在vc++中,无论是否自定义copy structor,都会产生NRV优化。
话说要产生NRV优化,要满足“函数中所有的路径都返回相同的具名数值 (Named Value)”,这里所说的所有的路径都返回相同的具名数值,我不知该理解为所有的路径都返回同一对象,还是理解为函数中只出现一个return语句。我在vc++的测试中,当函数中只出现一个return语句时才会产生NRV优化,即使连续两个一模一样的return语句,也会让NRV优化躲起来。在我转载的文章"Named Return Value Optimization 具名返回值优化"中,对于前一个问题已经进行了讨论,我在这也就不说多嘴了。这里只是说说两个return语句就能在vc++中消灭NVR优化的问题。
例:
定义如下类
class Test
{
public:
Test()
: m_x(0), m_y(0) { std::cout << "Test structor" << std::endl; }
Test(const Test &tst)
: m_x(tst.m_x), m_y(tst.m_y) { std::cout << "Test copy structor" << std::endl; }
~Test()
{ std::cout << "Test destructor" << std::endl; }
void setX(int x) { m_x = x; }
void setY(int y) { m_y = y; }
private:
int m_x;
int m_y;
};
写个如下函数
Test func(int x, int y)
{
Test xx;
xx.setX(x);
xx.setY(y);
return xx;
}
然后在main函数中如此
int main()
{
int x = 10;
int y = 20;
Test tt = func(x, y);
return 0;
}
够简单吧,按照NRV的说法,func会被转换成如下形式:
viod func(Test & __result, int x, int y)
{
//c++伪代码
__result.Test::Test();
__result.Test::setX(x);
__result.Test::setY(y);
return;
}
这样就节省了叫一个临时工xx对象的开资(在原始func代码中有这么一句 Test xx; )。别小看这么点开资,使用数目大了节约效果还是很显著的。
执行结果如下:
Test structor
Test destructor
注意:要把程序编译成Release版本,才会生成NRV优化后的代码。
如果在func函数后面加一个return语句,如下:
Test func(int x, int y)
{
Test xx;
xx.setX(x);
xx.setY(y);
return xx;
return xx;
}
则输出结果如下:
Test structor
Test copy structor
Test destructor
Test destructor
怎么样,是不是干掉了?