Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can subclass pointers strictly equal parent class pointers?

I was writing an operator== between two kinds of smart pointer and thought I should run a quick sanity check. I'm suprised by the result...

In the snippet below how is it that all variants of f and b end up with the same value?

struct Foo {
    int x;
};

struct Bar : public Foo {
    int y;
};

#include <iostream>

int main ()
{
    Bar bar;

    Foo * f = &bar;
    Bar * b = &bar;
    std :: cout << f << " " << b << " " << (f == b) << "\n";

    void * fv = f;
    void * bv = b;
    std :: cout << fv << " " << bv << " " << (fv == bv) << "\n";

    int fi = reinterpret_cast <int> (f);
    int bi = reinterpret_cast <int> (b);
    std :: cout << fi << " " << bi << " " << (fi == bi) << "\n";
}
like image 455
spraff Avatar asked Nov 29 '10 20:11

spraff


People also ask

Can a base class pointer point to a derived class object explain the limitations?

Explanation: A base class pointer can point to a derived class object, but we can only access base class member or virtual functions using the base class pointer because object slicing happens when a derived class object is assigned to a base class object.

Who can hold the address of a pointer to the base class?

By default base class pointer can hold the address of base class as well as derived call we all know. But if we don't use virtual keyword in base class then the base class pointer will call methods based on the type of pointer not on based on the value it holding.

Can this pointer point to another class?

It is true that a pointer of one class can point to other class, but classes must be a base and derived class, then it is possible.

What is base pointer and why it is being used?

The base pointer is conventionally used to mark the start of a function's stack frame, or the area of the stack managed by that function. Local variables are stored below the base pointer and above the stack pointer.


2 Answers

About the only time that a base class object won't have the same address as its subclass object is when multiple inheritance is involved.

In the above example memory probably looks like this:

                               / --------- \
                              /  | x     |  > This is the Foo portion of bar
This is the whole Bar object <   --------- /  
                              \  | y     |  
                               \ ---------  

Both views of the object have the same starting point, so a pointer to either view will have the same value.

In multiple inheritance, things get more complicated. Say you have:

struct Foo1{ int x; };
struct Foo2{ int y; };
struct Bar : public Foo1, public Foo2 { int z; };
Bar bar;

Now the memory will have to be laid out something like this:

                                / --------- \
                               /  | x     |  > This is the Foo1 portion of bar
                              /   --------- / \ 
This is the whole Bar object <    | y     |    > This is the Foo2 portion of bar  
                              \   ---------   /
                               \  | z     |  
                                \ ---------  

So &bar and (Foo1*)&bar will have the same value, while (Foo2*)&bar will have a different value, since it the Foo2 portion of the object starts at a higher address.

like image 145
Eclipse Avatar answered Oct 20 '22 18:10

Eclipse


This is the typical memory layout you will end up with:

Bar starts   Foo starts    x starts / ends  Foo ends   y starts / ends  Bar ends
|            |             |             |         |   |             |         |

Sice there is nothing between Bar start and Foo start, the offset of Foo can be zero, therefore the pointers for Bar, Foo and x might be identical.

like image 2
Šimon Tóth Avatar answered Oct 20 '22 18:10

Šimon Tóth