深度探索C++对象模型->2.3 程序转化语意学

一、 

 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 }
View Code

  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的语意学知识是非常重要的!

posted @ 2016-08-23 10:49  潇少爷  阅读(216)  评论(0编辑  收藏  举报