C++多继承的情况下派生类如果有N个含虚函数的基类,则派生类对象中会有几个虚表指针,1 还是N?

C++多继承的情况下派生类如果有N个含虚函数的基类,则派生类对象中会有几个虚表指针,1 还是N ?

N个
下面是一个简单的例子。

struct A {
    virtual void f() {}
};

struct B {
    virtual void g() {}
};

struct C : public A, public B {
    C() {}
    virtual void f() {}
    virtual void h() {}
};

int main()
{
    C c;
}

这是g++生成的汇编代码,可以看出C对象有两个虚表指针

A::f():
        push    rbp
        mov     rbp, rsp
        mov     QWORD PTR [rbp-8], rdi
        nop
        pop     rbp
        ret
B::g():
        push    rbp
        mov     rbp, rsp
        mov     QWORD PTR [rbp-8], rdi
        nop
        pop     rbp
        ret
A::A() [base object constructor]:
        push    rbp
        mov     rbp, rsp
        mov     QWORD PTR [rbp-8], rdi
        mov     edx, OFFSET FLAT:vtable for A+16
        mov     rax, QWORD PTR [rbp-8]
        mov     QWORD PTR [rax], rdx
        nop
        pop     rbp
        ret
B::B() [base object constructor]:
        push    rbp
        mov     rbp, rsp
        mov     QWORD PTR [rbp-8], rdi
        mov     edx, OFFSET FLAT:vtable for B+16
        mov     rax, QWORD PTR [rbp-8]
        mov     QWORD PTR [rax], rdx
        nop
        pop     rbp
        ret
C::C() [base object constructor]:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 16
        mov     QWORD PTR [rbp-8], rdi
        mov     rax, QWORD PTR [rbp-8]
        mov     rdi, rax
        call    A::A() [base object constructor]
        mov     rax, QWORD PTR [rbp-8]
        add     rax, 8
        mov     rdi, rax
        call    B::B() [base object constructor]
        mov     edx, OFFSET FLAT:vtable for C+16
        mov     rax, QWORD PTR [rbp-8]
        mov     QWORD PTR [rax], rdx
        mov     edx, OFFSET FLAT:vtable for C+48
        mov     rax, QWORD PTR [rbp-8]
        mov     QWORD PTR [rax+8], rdx
        nop
        leave
        ret
C::f():
        push    rbp
        mov     rbp, rsp
        mov     QWORD PTR [rbp-8], rdi
        nop
        pop     rbp
        ret
C::h():
        push    rbp
        mov     rbp, rsp
        mov     QWORD PTR [rbp-8], rdi
        nop
        pop     rbp
        ret
main:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 16
        lea     rax, [rbp-16]
        mov     rdi, rax
        call    C::C() [complete object constructor]
        mov     eax, 0
        leave
        ret
vtable for C:
        .quad   0
        .quad   typeinfo for C
        .quad   C::f()
        .quad   C::h()
        .quad   -8
        .quad   typeinfo for C
        .quad   B::g()
vtable for B:
        .quad   0
        .quad   typeinfo for B
        .quad   B::g()
vtable for A:
        .quad   0
        .quad   typeinfo for A
        .quad   A::f()
typeinfo for C:
        .quad   vtable for __cxxabiv1::__vmi_class_type_info+16
        .quad   typeinfo name for C
        .long   0
        .long   2
        .quad   typeinfo for A
        .quad   2
        .quad   typeinfo for B
        .quad   2050
typeinfo name for C:
        .string "1C"
typeinfo for B:
        .quad   vtable for __cxxabiv1::__class_type_info+16
        .quad   typeinfo name for B
typeinfo name for B:
        .string "1B"
typeinfo for A:
        .quad   vtable for __cxxabiv1::__class_type_info+16
        .quad   typeinfo name for A
typeinfo name for A:
        .string "1A"