读《C++对象模型》- 构造、解构、拷贝语意学

constructor可能内带大量的隐藏码,因为编译器会扩充每一个constructor,扩充程度视class的继承体系而定。一般而言编译器所做的扩充操作大约如下:

  1. 记录在member initialization list中的data members初始化操作会被放进constructor的函数本身,并以members的声明顺序为顺序。
  2. 如果有一个member并没有出现在member initialization之中,但它有一个default constructor,那么该default constructor必须被调用。
  3. 2之前,如果class object有virtual table pointer(s),它(们)被设定初值,指向适当的virtual table(s)。
  4. 3之前,所有上一层的base class constructors必须被调用,以base class的声明顺序为顺序:
    • 如果base class被列于member initialization list中,那么任何明确指定的参数都应该传递过去。
    • 如果base class没有被列于member initialization list中,而它有default constructor,那么就调用之。
    • 如果base class是多重继承下的第二或后继的base class,那么this指针必须有所调整。
  5. 4之前,所有virtual base class constructors必须被调用,从左到右,从最深到最浅:
    • 如果class被列于member initialization list中,那么如果有任何明确指定的参数,都应该传递过去。若没有列于list之中,而class中一个default constructor,也应该调用之。
    • 此外,class中的每一个virtual base class subobject的偏移量(offset)必须在执行期可被存取。
    • 如果class object是最底层的(most-derived)的class,其constructors可能被调用;某些用以支持这个行为的机制必须被放进来。

对于虚拟继承,可以在derived class的constructor函数中加入条件式的测试参数,用来决定调用还是不调用相关的virtual base class constructors。

对象定义的析构函数的执行顺序和构造的顺序相反:

  1. destructor的函数本身首先被执行。
  2. 如果class拥有member class object,而后者拥有destructors,那么它们会以其声明顺序的相反顺序被调用。
  3. 如果object内带一个vptr,则现在被重新设定,指向适当之base class的virtual table。
  4. 如果有任何直接的(上一层)nonvirtual base classes拥有destructor,它们会以其声明顺序的相反顺序被调用。
  5. 如果有任何virtual base class拥有destructor,而当前讨论的这个class是最尾端(most -derived)的class,那么它们会以原来的构造顺序的相反顺序被调用。
This entry was posted in C/C++. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>