Varun
Varun

Reputation: 477

Multiple Inheritance: Different Address same address

I have written a sample program. If I print the address of pa and pb both are different. Can you let me know why is this happening ?

#include<iostream>
using namespace std;
class A {
int x;
};

class B {
int y;
};

class C: public A, public B {
int z;
};

int main()
{
 C c;
 A *pa;
 B *pb;

 pa = &c;
 pb = &c;

cout<<pa<<endl;
cout<<pb<<endl;

}

Upvotes: 6

Views: 737

Answers (3)

Jonathon Reinhart
Jonathon Reinhart

Reputation: 137517

As Kerrek SB put it, pa and pb in your example don't actually point to c, but rather to the A and B subobjects of c.

With multiple inheritance, the data from the base classes is essentially stacked one after another. Base-typed pointers are simply offset to the data for that base class. Because of this, pa and pb point at different offsets into c.

#include<iostream>
using namespace std;

class A {
    public:
    int x;
};

class B {
    public:
    int y;
};

class C: public A, public B {
    public:
    int z;
};

int main()
{
    C c;
    cout << "    &c: " << &c << endl << endl;

    cout << "(A*)&c: " << (A*)&c << endl;
    cout << "(B*)&c: " << (B*)&c << endl << endl;

    cout << "  &c.x: " << &c.x << endl;
    cout << "  &c.y: " << &c.y << endl;
    cout << "  &c.z: " << &c.z << endl << endl;
}

Result:

    &c: 0x7ffdfeb26b20

(A*)&c: 0x7ffdfeb26b20
(B*)&c: 0x7ffdfeb26b24

  &c.x: 0x7ffdfeb26b20
  &c.y: 0x7ffdfeb26b24
  &c.z: 0x7ffdfeb26b28

So you can see that C is laid out like this:

                  ---------------
0x7ffdfeb26b20    |     x       |     class A data
                  ---------------
0x7ffdfeb26b24    |     y       |     class B data
                  ---------------
0x7ffdfeb26b28    |     z       |     class C data
                  ---------------

If you add some virtual methods to this example, you'll see that the same things happens with the subclass vtables.

Upvotes: 8

David van rijn
David van rijn

Reputation: 2220

Back in the good old days of plain c, there were just structs.

struct Base{
   int baseMember;
}

struct Child{
   struct Base parent;
   int someMoreMembers;
}

this way, dereferencing a pointer to a Child as if it were a base pointer, would result in a perfectly good pointer to the Base, because it is the first member. In c++ this still works the same way (usually). But if you now inherit two classes, you cannot put them both as first member in your struct. So C++ converts a pointer to a base into a pointer to the child by adding the offset the specific base data is at.

Upvotes: 1

kiviak
kiviak

Reputation: 1103

    ---------   <------pa = &c
   |    x    |
    ---------   <------pb = &c
   |    y    |
    ---------
   |    z    |
    ---------

it depends on the memory model of the class, above is an object of class C in memory

Upvotes: 0

Related Questions