12.5 本章小结
本章讲解了对象之间发生继承和派生关系后的内存布局情况,以及相关的处理和操作。读者应该结合C++语法上机进行验证,以熟悉各种内存布局。因为对象之间的关系结构不同,所以它们的内存布局、构造函数、析构函数都有差别,这些是编译器作者为了实现C++的语法而设计的内存结构和执行代码。在其他的编译环境下,其内存结构和相关的处理会有差异,由于不同的C++编译器都需要满足C++的语法标准,故差异也不会太大。要分析由其他编译器创建的程序,可先编写一些简单的语法示例(类似于本章体现各个语法知识点的示例),然后用其他编译器编译,通过反汇编观察其内存布局、构造函数和析构函数的处理流程。
思考题答案:
为什么编译器要在子类析构函数中再次将虚表设置为子类虚表呢?这个操作非常必要,因为编译器无法预知这个子类以后是否会被其他类继承,如果被继承,原来的子类就成了父类,析构函数执行时会先执行当前对象的析构函数,然后向祖父类的方向按继承线路逐层调用各类析构函数,当前对象的析构函数开始执行时,其虚表也是当前对象的,因此执行到父类的析构函数时,虚表必须改写为父类的虚表。编译器所产生的类实现代码,必须能够适应将来不可预知的对象关系,故在每个对象的析构函数内,要加入填写自己虚表的代码。