Difference in Address of base and derived objects using *this vs using & operator

492 Views Asked by At

Can someone try to explain me why i get a difference in address of base and derived object while using this pointer and & operator. Below is my code

#include <iostream>

using namespace std;

class A
{
    public:
     A()
     {
         cout<<"Base Address "<<this<<endl;
     }
};
class B:public A
{
    public:
    B()
    {
        cout<<"Deri Address "<<this<<endl;
    }
};
int main()
{
    B b;

}

The O/P is 
Base Address 0x7fff500e9bdf
Deri Address 0x7fff500e9bdf

Both are same.

When i add two more statements in the main as shown below

#include <iostream>

using namespace std;

class A
{
    public:
     A()
     {
         cout<<"Base Address "<<this<<endl;
     }
};
class B:public A
{
    public:
    B()
    {
        cout<<"Deri Address "<<this<<endl;
    }
};
int main()
{
    B b;
    A a;
   cout<<&a<<endl<<&b<<endl;

}

The O/P is as shown below

Base Address 0x7fff82c696df
Deri Address 0x7fff82c696df
Base Address 0x7fff82c696de
0x7fff82c696de
0x7fff82c696df

Now I could clearly see the address differs

a) What could be the reason for this difference
b) One more thing i wanted to know is if the base sub object in derived class is exactly same as the base object? I am confused about this because if we say in a base class if we have a variable x and if we have a derived class for this base class(non polymorphic case) now if we talk about the base sub object in derived, is it the same x present in base class is also present in the base sub object of derived class (i mean the variable with same address in both base and base sub object in derived) or we have a separate copy of x in both base and base sub object of derived(i mean the variable with different address)

Please clarify?
3

There are 3 best solutions below

0
On

You have two objects: a and b:

a with address 0x7fff82c696de

b with address 0x7fff82c696df

0
On

Why do you get what you see? well it's because a != b You do create 2 objects:

A a;
B b;

It clearifies if you add another parameter to your class A's constructor

class A
{
    public:
     A(std::string name)
     {
         cout<<name<<"'s Base Address "<<this<<endl;
     }
};

and modify your main function a bit

int main()
{
    B b("b");
    A a("a");
   cout<<"a: "<<&a<<endl<<"b: "<<&b<<endl;

}

Now your output will look like this

b's Base Address 0x7fff82c696df
b's Deri Address 0x7fff82c696df
a's Base Address 0x7fff82c696de
a: 0x7fff82c696de
b: 0x7fff82c696df

Now you can see that thr result of & operatorand *this are equal. You just have tow different objects with, of course, two different addresses. You also see that for derived class B, this has the same value in Bs and As constructor.

4
On

I think the first thing to clarify for you is understanding difference between class vs object. A class is a blueprint whereas object is an instance of the class.

So, if you don't create an instance of the class, then you have nothing on the memory.

In the first case, the addresses printed are the same because you created one instance. It make sense to have the same address because of having only one single object.

In the second case, the addresses are different because of having two different objects (two instances of the class are created) not because of using &. So, the following code prints the same addresses.

#include <iostream>

class A
{
public:
    A() { std::cout << "Address with this pointer: " << this << std::endl; }
};

int main()
{
    A a;
    std::cout << "Address with & operator: " << &a << std::endl;
}

Edit: Why represents the same address for sub-object

As I mentioned in the comments, I never heard the term sub-object. But I got the below definition from here.

subobject: Any object that is stored within another object (array elements, base class objects and data member objects).

An object naturally occupies a memory and any sub-object of the object needs to seat somewhere in that memory. The first created sub-object (in terms of order of definition) gets the first portion of the memory, second created sub-object gets the second portion of the memory right after first object and so on. So, first created sub-object has the same starting address with the object itself. In the following code, the fist created object is instance of Class A ( So A and C have the same address) just because Class A is inherited before than Class B. If you change class C : public A, public B to class C : public B, public A, then objects of class B and class C would be the same.

#include <iostream>

class A
{
public:
    A() { std::cout << "Address of Sub-Object A: " << this << std::endl; }
    int x;
};


class B
{
public:
    B() { std::cout << "Address of Sub-Object B: " << this << std::endl; }
    int y;
};

class C : public A,  public B {
public:
    C() : A() , B() { std::cout << "Address of Object C:     " << this << std::endl; }
    int z;

};

int main()
{
  C c;
}

PS: if you think about composition rather than inheritance, then it might be more easier to understand.