DawidPi DawidPi - 2 months ago 9
C++ Question

Class inheritance chain and pointers to each of classes

So given simple code like following:

class A{
public:
virtual void foo() const { cout << "foo in A." << endl;}
private:
int a;
};

class B: public A{int c;};

class C : public B{
public:
void foo() const override {cout << "foo in B." << endl;}
private:
int a;
int b;
};


now, when I create the object of type C I can imagine its layout in the memory like this:

+----------------+
| C (int) |
|+--------------+|
|| B (+1) ||
||+------------+||
||| A (2int) |||
||+------------+||
|+--------------+|
+----------------+


so now simple code:

C objectC;
A* aPtr = &objectC;
B* bPtr = &objectC;
C* cPtr = &objectC;


I would expect, that even though compiler generates code, which makes the following expression return true:

(aPtr == bPtr && bPtr == cPtr)


the following expression should return false:

((int)aPtr == (int)bPtr && (int)bPtr == (int)cPtr)


but on my PC it returned also true. Also after printing out the numerical values of pointers they were also the same.

My question is why does the expected result did not come after running program? Is there some C++ document specifying the exact behavior of pointer's values in situations like this or it's more like compiler dependant thing?

Answer

The layout of the object is more likely to be the reverse of what you have shown.

+----------------+ +     +
|    A (int)     | |     |
+----------------+ |  B  |
| delta  B (2 int) |     |  C
+------------------+     |
| delta  C (int)         |
+----------------------- +

It makes sense that the numerical value of aPtr, bPtr, and cPtr will be the same when such a layout is used by a compiler.

I haven't heard of any compiler that creates an object layout like you suggested. I am not saying definitively that there aren't any, it's just that I haven't heard of them.