全面解析C++中的析构函数

2020-01-06 14:25:24王旭

  • class A
  • class B
  • class C : virtual public A, virtual public B
  • class D : virtual public A, virtual public B
  • class E : public C, public D, virtual public B

    为了确定 E 类型的对象的虚拟基类的析构顺序,编译器将通过应用以下算法来生成列表:

    1. 向左遍历关系图,并从关系图中的最深点开始(在此示例中,为 E)。
    2. 执行左移遍历,直到访问了所有节点。记下当前节点的名称。
    3. 重新访问上一个节点(向下并向右)以查明要记住的节点是否为虚拟基类。
    4. 如果记住的节点是虚拟基类,请浏览列表以查看是否已将其输入。如果它不是虚拟基类,则将其忽略。
    5. 如果记住的节点尚未包含在列表中,请将其添加到列表的底部。
    6. 向上遍历关系图并沿下一个路径向右遍历。
    7. 转到步骤 2。
    8. 在用完最后一个向上路径时,请记下当前节点的名称。
    9. 转到步骤 3。
    10. 继续执行此过程,直到底部节点再次成为当前节点。

    因此,对于 E 类,析构顺序为:

    1. 非虚拟基类 E。
    2. 非虚拟基类 D。
    3. 非虚拟基类 C。
    4. 虚拟基类 B。
    5. 虚拟基类 A。

    此过程将生成唯一项的有序列表。任何类名均不会出现两次。在构造列表后,将以相反的顺序遍历该列表,并且将调用列表中每个类(从最后一个到第一个)的析构函数。