Allanqunzi
Allanqunzi

Reputation: 3260

base class is a reference to another object

I just encountered a snippet of code which seems quite strange to me(see below as a minimal example), the derived::base is a reference to another object of type of base, can someone help me to answer the questions in the comments?

class base{
public:
   int a;
   int b;
};

class derived : public base{
public:
   double c;
   void run(const base & bs){
     ((base &) *this) = bs; // what does this line do? 
                            // Is derived::base now a copy of bs? 
                            // If yes, but why not write ((base) *this) = bs?
                            // if not, then derived::base is a reference to bs, 
                            // then does it mean the memory of derived::base
                            // and members of derived are no longer contiguous?
     std::cout << "a = " << a << std::endl;

   }
};

PS

comments by @LightnessRacesinOrbit helped a lot to clear the questions, but I can only accept an answer post, the best is by @WhiZTiM

Upvotes: 1

Views: 78

Answers (2)

WhiZTiM
WhiZTiM

Reputation: 21576

void run(const base & bs){
     ((base &) *this) = bs; 
     std::cout << "a = " << a << std::endl;
}

The above code can be broken down as:

void run(const base & bs){
     base& base_of_this_instance = *this; 
     base_of_this_instance = bs;
     std::cout << "a = " << a << std::endl;
}

The memory for an object of derived may be laid out as:

||  int a  |x|  int b  |y|  int c  ||   // <- x and y represents some hypothetical padding
||        base         |y|         ||   // <- We can slice `derived` and retrieve only base
||           derived               ||   // <- Memory consumed by derived

In your derived::run method, first, a reference to the base portion of derived is obtained, secondly that base is assigned to bs. This assignment will invoke the copy assignment operator of base. That means the base portion will now now hold a copy of whatever was in bs.

Upvotes: 2

MaxV
MaxV

Reputation: 2800

The result of

((base &) *this)

is references to base class

You can save it to a variable:

base& refToBase = ((base &) *this);

refToBase is a reference to the same object which is this

After that you have assignment

refToBase = bs;

It will assign bs's value to refToBase object

Like this:

int i = 10;
int p = 20;
int& refI = i;
int& refP = p;
refI = refP; // i == 20
p = 15; // p ==15 but i == 20

So after "strange code" from your example are executed we have the copies of bs.a and bs.b in derived::a and derived::b

the memory of derived::base and derived::c is still one batch

Upvotes: 0

Related Questions