0

This is modification of question and code presented in this link: C++ multiple inheritance and vtables. I understood from this link how vptr & vtable are setup.

My question is how does, bp->OutB() retrieves value of int a, which is member of classA. I thought we pass this pointer to this method which looks at B part of class C. Specifically, Memory layout of classC assuming 32 bit.

&obj.
+0: vptr( pointer to virtual method table of classC( for classA).
+4: value of a.
+8: vptr( pointer to virtual method table of classC( for classB).
+12: value of b.
+16: value of c.

My questions is, we pass &obj+8 as this pointer to when we execute: bp->OutB(), but how does it end up retrieving member: int a of class A in that case.

#include <iostream>
using namespace std;

class A
{
    public:
    virtual void OutA() = 0;
    int a;
};

class B
{
    public:
    virtual void OutB() = 0;
    int b;
};

class C : public A, public B
{
    void OutA();
    void OutB();
    int c;
};

void C::OutA()
{
    cout << "Out A " << endl;
}

void C::OutB()
{
    cout << "Out B " << " a is: " << a << endl;
}

int main()
{
    C obj;
    obj.a = 10;
    obj.b = 20;
    obj.c = 30;
    obj.OutA();
    obj.OutB();
    A* ap = (A*)&obj;
    B* bp = (B*)&obj;
    ap->OutA();
    bp->OutB();
    return 0;
}
nonenone
  • 120
  • 1
  • 3
  • 9
  • If you expected it to print anything other then `a is: 10` you have clearly misunderstood something. The implementation of `C::OutB` prints `a`. What pointer you are using to access the object is completely irrelevant. – super Jan 14 '20 at 02:22
  • My point is main reason why compiler adjust pointers is to make it as if it has got instance of classB when we do this B* bp = (B*)&obj. Basically its not pointing at original address of object obj but adds offset to it so that any method of classB will feel as if they are passed this pointer of instance of classB. But it is still able to access a so i suspect compiler is again calculating offset to get int a. If that is case why does it has to pass offset within c to the class B pointer in this case. – nonenone Jan 14 '20 at 03:13
  • `C` contains both an `A` and a `B`. In this case `A` and `C` will share the same adress and `B` will be at an offset (size of A + possible align). The compiler can cast between all these 3 pointers. I still don't understand what that has got to do with access to data members, or what you are confused about. There would still be an offset without any virtual functions and vtable. – super Jan 14 '20 at 03:51
  • @super: I am not sure are you getting how vpointer and vtable is organized in multiple inheritance. – nonenone Jan 14 '20 at 03:58
  • 2
    The point I'm making is that no matter how the vtables are organized (as far as the language is concerned there does not even have to be a vtable. It's an implementation detail) it has no impact on how the compiler would resolve the address of `a`. – super Jan 14 '20 at 04:09

0 Answers0