are vptr and vtable inherited from base class?

559 views Asked by At

As can be seen, D3 introduces a new virtual function, @function3(), in the middle of the chain of inheritance. I am wondering what is happening with *--vptr and vtable when this happens. D3 is a 'kind of' a new base class now,

class Base {
public:
    virtual void function1() { std::cout << "Base func1()\n"; };
    virtual void function2() { std::cout << "Base func2()\n"; };
};

class D1 : public Base {
public:
    virtual void function2() { std::cout << "D1 func2()\n"; };
};

class D2 : public D1 {
public:
    virtual void function1() { std::cout << "D2 func1()\n"; };
};

class D3 : public D2 {
public:
    virtual void function2() { std::cout << "D3 func2()\n"; };
    virtual void function3() { std::cout << "D3 func3()\n"; };
};

class D4 : public D3 {
public:
    virtual void function1() { std::cout << "D4 func1()\n"; };
    virtual void function3() { std::cout << "D4 func3()\n"; };
};

int main() {
    D3 d3;  
}

https://imgur.com/a/sxFzrKG

but when I see vtable entries, what I can see are function1(), function2(). I thought entries have to be function2(), function3(). Why can't I get what I thought?

2

There are 2 answers

1
krisz On BEST ANSWER

The vtable contains all inherited virtual functions and any newly introduced one.

Here is the vtable for D3 generated by MSVC:

const D3::`vftable' DD  FLAT:const D3::`RTTI Complete Object Locator'  ; D3::`vftable'
        DD      FLAT:virtual void D2::function1(void)
        DD      FLAT:virtual void D3::function2(void)
        DD      FLAT:virtual void D3::function3(void)

The reason why the debugger doesn't show all of them might be a bug or a limitation.

0
SergeyA On

Not clear what you mean by 'what is happening'. All vtables are specific to class (type). vtable for D1 is different from vtable for D2, and so forth.

Vtable for D3 has more functions in it, than D1 one. You can normally call those functions if your static type is D3 or D4, but can't call those if your static type is D1 or D2.