标签:
一、
1、显示的初始化操作:
X x0; void foo_bar() { X x1(x0); X x2 = x0; X x3 = X(x0); }
会被转换成如下步骤(双阶段转化):
1 void foo_bar() 2 { 3 X x1; 4 X x2; 5 X x3; 6 7 x1.X::X(x1); 8 x2.X::X(x2); 9 x3.X::X(x3); 10 }
2、参数(形参)的初始化:
1 void foo(X x0);//声明 2 3 X xx; 4 foo(xx); 5 //会被转换成实际如下: 6 voif foo(X& x0); 7 8 X _temp0; 9 _temp0.X::X(xx); 10 foo(_temp0);
另一种方法是:以“拷贝建构”的方式把实际参数直接健在其应该的位置上。
3、返回值的初始化:
已知下面这个函数定义:
X bar() { X xx; //处理xx return xx; }
那么该函数是如何把返回值返回的呢?实际上是个双转换过程:
①:首先加一个额外参数,类型是class object的一个reference。
②在return语句之前安插一个copy constructor调用操作,以便将欲返回之object的内容做上述新增参数的初值。
以下是上述函数的转换后的代码:
void bar(X& _result) { X xx; xx.X::X(); //处理xx _result.X::XX(xx); return; }
二、我们已知上面的转换过程,那么如何改善会使效率得到提升呢?
1、在使用者层面做优化:
以下是以往代码的风格
X bar(const T& y, const T& z) { X xx; return xx; }
将会被以下风格所替代:
X bar(const T& y, const T& z) { return X(y,z) }
虽然通过上述方式省略了copy constructor,但是会使特殊用途的constructor大量扩散。
2、在编译器层面做优化:
采用所谓的Named Return Value(NRV)优化,以下是NRV优化的过程:
X bar() { X xx; return xx; } //会被以下替代: X bar(X& _result) { _result.X::X(); return; }
注:当class缺少copy constructor时,编译器将不能做NRV优化(原因不知)。
3、NRV优化确实得到了效率上的改善,但是却饱受批评,原因如下:
①:用户无法得知NRV是否真的完成。
②:一旦函数变得十分复杂,NRV将难以施行。当所有的named return指令语句发生于函数的top level,优化才施行。
③:
4、copy constructor可能会被征以效率税,例如下面的代码:
X xx0(1024); X xx1 = X(1014); X xx2 = (X)1014; //xx0的实际过程 xx0.X::X(1024); //xx1和xx2的实际过程 X _temp0; _temp0.X::X(1024); xx.X::X(_temp0); _temp0.X::~X();
三、
copy构造函数中使用memcpy()和memset()是效率最高的方式,但是当class内含有virtual functions或内含一个virtual base class时,上述代码将难以正确执行,因为编译器会添加一些代码,所以这种情况下,掌握某些C++ Object Model的语意学知识是非常重要的!
标签:
原文地址:http://www.cnblogs.com/linux-hp/p/5798373.html