Virtual destructors and deleting objects with multiple inheritance… How does it work?

后端 未结 4 1712
既然无缘
既然无缘 2020-12-14 07:45

First, I understand why virtual destructors are needed in terms of single inheritance and deleting an object through a base pointer. This is specifically about

4条回答
  •  一个人的身影
    2020-12-14 08:07

    It works because the standard says that it works.

    In practice, the compiler inserts implicit calls to ~A() and ~B() into ~AB(). The mechanism is exactly the same as with single inheritance, except that there are multiple base destructors for the compiler to call.

    I think the main source of confusion in your diagram is the multiple separate vtable entries for the virtual destructor. In practice, there will be a single entry that would point to ~A(), ~B() and ~AB() for A, B and AB() respectively.

    For example, if I compile your code using gcc and examine the assembly, I see the following code in ~AB():

    LEHE0:
            movq    -24(%rbp), %rax
            addq    $16, %rax
            movq    %rax, %rdi
    LEHB1:
            call    __ZN1BD2Ev
    LEHE1:
            movq    -24(%rbp), %rax
            movq    %rax, %rdi
    LEHB2:
            call    __ZN1AD2Ev
    

    This calls ~B() followed by ~A().

    The virtual tables of the three classes look as follows:

    ; A
    __ZTV1A:
            .quad   0
            .quad   __ZTI1A
            .quad   __ZN1AD1Ev
            .quad   __ZN1AD0Ev
    
    ; B
    __ZTV1B:
            .quad   0
            .quad   __ZTI1B
            .quad   __ZN1BD1Ev
            .quad   __ZN1BD0Ev
    
    ; AB
    __ZTV2AB:
            .quad   0
            .quad   __ZTI2AB
            .quad   __ZN2ABD1Ev
            .quad   __ZN2ABD0Ev
            .quad   -16
            .quad   __ZTI2AB
            .quad   __ZThn16_N2ABD1Ev
            .quad   __ZThn16_N2ABD0Ev
    

    For each class, entry #2 refers to the class's "complete object destructor". For A, this points to ~A() etc.

提交回复
热议问题