构造函数

来源:互联网 发布:淘宝公众号 编辑:程序博客网 时间:2024/06/05 05:11

什么时候一个class不展现出“bitwise copy semantics”呢?有4种情况:

1、当class内含一个member object而后者的class声明有一个copy constructor时。
2、当class继承自一个base class而后者存在一个copy constructor时(再次强调,不论是被显示声明或是被合成而得)。
3、class声明了一个或多个virtual functions时。
4、当class派生自一个继承串链,其中有一个或多个virtual base classes时。
前两种情况种,编译器必须将member或base class的“copy constructors调用操作”安插到被合成的copy constructor中。

重新设定Virtual Table的指针
编译期间的两个程序扩张操作(只要有一个class声明了一个或多个virtual functions就会如此):
1、增加一个virtual function table (vtbl),内含每一个有作用的virtual function的地址。
2、一个指向virtual function table的指针(vptr),安插在每一个class object内。
如果编译器对于每一个新产生的class object的vptr不能成功而正确地设好其初值,将导致可怕的后果。因此,当编译器导入一个vptr到class之中时,该class就不再展现bitwise semantics了。现在,编译器需要合成出一个copy constructor以求将vptr使当地初始化。
当一个base class object以其derived class内容做初始化操作时,其vptr复制操作也必须保证安全,合成出显示设定object的vptr指向其类的virtual table,而不是直接从右手边的class object中将其vptr现值拷贝出来。

处理Virtual Base Class Subobject
一个virtual base class的存在会使bitwise copy semantics无效。再则,问题并不发生于“一个class object以另一个同类的object作为初值”之时,而是发生于“一个class object以其derived classes的某个object作为初值”之时。在这种情况下,编译器必须合成一个copy constructor,安插一些代码以设定virtual base class pointer/offset的初值(或简单地确定它没有被抹消),对每一个members执行必要的memberwise初始化操作,以及执行其他的内存相关工作。

在下列情况下,为了让你的程序能够被顺利编译,你必须使用member initialization list:
1、当初始化一个reference member时;
2、当初始化一个const menber时;
3、当调用一个base class的constructor,而它拥有一组参数时;
4、当调用一个member class的constructor,而它拥有一组参数时。

注意:list中的项目顺序是由class中的members声明顺序决定的,不是由initialization list中的排列顺序决定的。initialization list的项目被放在explicit user code之前。

0 0
原创粉丝点击