【C++】深度探索C++对象模型读书笔记--构造函数语义学(The Semantics of constructors)(三)

程序转化语义学(Program Transform Semantics)

显式的初始化操作

  已知有这样的定义:

  X x0;

  下面的三个定义每一个都明显地以x0来初始化其class object:

  void foo_bar(){

    X x1(x0);

    X x2 = x0;

    X x3 = X(x0);

  }

  必要的程序转化有两个阶段:

  1.重写每一个定义,其中的初始化操作会被剥除。(在严谨的C++用词中,“定义”是指“占用内存的行为)

  2. class的copy constructor调用操作会被安插进去

  上面的例子转化之后称为这样子:  

  

void foo_bar() {
    X x1; 
    X x2;
    X x3;

    //编译器安插 X copy consruction的调用操作
    x1.X::X(x0);
    x2.X::X(x0);
    x3.X::X(x0);
}

 

  其中的:

  x1.x::X(x0);

  就表现出对以下的copy constructor的调用:

  x::X(constructor X& xx);

 

参数初始化:

  C++标准中说,把一个class object当作参数传给一个函数(或当作一个函数的返回值),相当于以下形式的初始化操作:

  X xx = arg;

  其中xx代表形式参数(或返回值)而arg代表真正的参数值。因此这个函数:

  void foo(X x0);

  下面的调用方式:

  X xx;

  foo(xx);

  被转化为:

  

//编译器产生出来的临时对象
 X _temp0;

//编译器对copy constructor的调用
_temp0.X::X(xx);

//重新改写函数调用操作,以便试用上述的临时对象
foo(_temp0);

//临时性object以class X的copy constructor正确地设定了初值,然后再以bitwise方式拷贝到x0,这个局部实例中,所以foo()的声明也必须被转化
void foo(X& x0);

  其中class X声明了一个destructor,它会在foo()函数完成之后被调用,对付那个临时性的object。

 

返回值的初始化:

  已知下面这个函数定义:

  

X bar()
{
    X xx;
    return xx;
}

  编译器将会执行一个双阶段转化:

  1. 首先加上一个额外参数,类型是class object的一个reference。这个参数将用来放置被拷贝构建(copy constructed)而得的返回值。

  2. 在return指令之前安插一个copy constructor调用操作,以便将欲传回给object的内容当作上述新增参数的初值。

  根据这样的算法,bar()转换如下:

  

//函数转换
//以反映出copy constructor的应用

void bar(X &_result) //加上一个额外参数
{
    X xx;
    
    //编译器所产生的default constructor调用操作
    xx.X::X()

    //...处理xx

    //编译器所产生的copy constructor调用操作
    _result.X::XX(xx);

    return;
}

  现在编译器必须转换为每一个bar()调用操作,以反映其新定义。例如:

  

X xx = bar()

  将被转化为下列两个指令:

  

//注意,不必施行default constructor
X xx;
bar(xx);

 

  

 

posted @ 2015-07-14 22:45  vincently  阅读(163)  评论(0编辑  收藏  举报