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

来源:互联网 发布:淘宝韩国第一美女模特 编辑:程序博客网 时间:2024/06/09 17:16

以下包括编译器调用拷贝构造函数的策略,以及这些怎么影响程序,拷贝构造函数的应用,使编译器作一些转化

编译器通常的3种转化

1显示的初始化操作的转化

如果定义 X x0;对于下图三种显示初始化:

编译器对程序的转化包括两个阶段

(1)重写每一个定义,并且其中的初始化操作会被剥夺

(2)class的拷贝构造函数调用操作会被安插进去

即经过转化后,程序可能如下:

2 参数的初始化的转化

在C++中,把一个类对象当作参数传递给一个函数(或作为函数返回值),相当于以下操作:

    X    xx = arg;  //xx代表形参或返回值,arg代表真正的参数。

若已知函数: void foo(X  x0);

调用方式    X  xx;  foo(xx);   这要求x0以memberwise的方式将xx作为储值初始化。编译器对这种的转化如下

1  导入临时性object,并调用拷贝构造函数将它初始化,然后将临时性object交给函数

2  foo()的声明也被转换,形参从类X对象编程一个类X的引用

如下:


foo调用完成后,调用析构函数删除临时性对象

对于该类型的另一种实现方法是“拷贝构建”,即把实际参数值直接构建在其对应的位置上。

3  返回值的初始化

如上面的程序断,返回值从局部对象xx拷贝过来的过程,cfront中分两个阶段转化:

(1)首先加一个额外参数(第一个参数),类型是X对象的引用,参数用来放置“拷贝构建”而得的返回值

(2)return之前安插一个拷贝构造函数,将预传回去的Object内容当作函数初值。

之后不用传回任何值。如下

之后对bar()函数的所有调用都将改成转换成的定义。


对于拷贝构造函数,一个优化是可以由程序员自己优化,即如果返回一个类对象,有时可以return 语句中直接返回构造的对象。

编译层的优化:NRV

还是返回值转化的例子,NRV优化是将_result直接取代xx,而不是先计算了xx,在用xx构造result,返回result.即程序修改如下:

导致编译器实施NRV优化,需要该类有拷贝构造函数,无论是显示构造的还是合成的。编译器实施NRV操作一般会使程序变快。


拷贝构造函数需要还是不需要,有种情况需要: 如果类是基本类型,但有很多成员拷贝初始化操作,或者以值传递回objects.这时如果声明了拷贝构造函数(本来无用的),但是这个动作会触发编译器的NRV优化,所以拷贝构造函数是需要的。

如果程序员了解编译器关于拷贝构造函数进行的转化,可以控制程序的执行效率,如以上这种情况,本来是不需要拷贝构造函数的,但是如果定义了,编译器会启动优化,会大大加快程序的运行。


对于C++的成员初始化列表,在以下情况下必须使用

1 当初始化一个reference member时

2 当初始化一个const member时

3 当调用一个base class的构造函数,而它拥有一组参数时

4 当调用一个member class的constructor,而它拥有一组参数时。

在成员初始化列表中初始化类成员,可以提高速度,因为免去了调用一次拷贝构造函数和赋值构造函数的开销,也没有临时对象的产生。

写在初始化列表中,编译器将会把这个操作写进函数,并直接调用构造函数。没有临时对象的产生。

编译器对初始化列表的处理:会一一操作列表的内容,以适当顺序在constructor之内安插初始化操作,并且在任何explicit user code之前。并且这些构造函数的初始化顺序是根据类中成员声明顺序决定的,不是初始化列表中的顺序。


0 0
原创粉丝点击