3

How come my compiler does not give me a warning or an error for this code:

class A {};
class B : public A{};
class C : public A{};
int main(int argc,char** args)
{
    B b;
    A& a = b;
    C c;
    a = c;
}

I would tend to think that this would result in the data being stored in the "b" variable is no longer of type "B" and is going to give me a bunch of problems....so why am I able to do this.

DarthRubik
  • 3,927
  • 1
  • 18
  • 54

3 Answers3

1

a = c; performs assignment between the A part of b, and the A part of c. The B and C parts (if any) of those objects are unmodified.

In general this is kind of dangerous as the B and C objects may not have been designed to have only their A sub-object assigned. On this thread are various other suggestions for handling operator= in a class hierarchy.

Community
  • 1
  • 1
M.M
  • 138,810
  • 21
  • 208
  • 365
1

See comments:

class A {};
class B : public A{};
class C : public A{};
int main(int argc,char** args)
{
    B b; // memory allocated for b to contain A+B
    A& a = b; // a is referencing A part of A+B
    C c; // memory allocated for c to contain A+C
    a = c; // a (A part of A+B) is overwritten from A part of A+C, c is sliced into a
}

Hope that helps.

Riad Baghbanli
  • 3,105
  • 1
  • 12
  • 20
1

How come my compiler does not give me a warning or an error?

A class has a copy constructor and assignment operator by default if they were not declared explicitly. As a result, an instance of derived class (C) can be assigned to a variable of the base class type (A). This effect is known as slicing.

To prevent from this you can disable copy constructor and assignment operator in the base class:

class A 
{
   protected:
     A() = default;
     A(const A & source) = delete;
     A & operator = (const A & source) = delete;
};

 class B : public A{};
 class C : public A{};


 int main(int argc,char** args)
 {
    B b;
    A& a = b;
    C c;
    a = c;  // this will not compile
}   
Community
  • 1
  • 1
alexm
  • 6,854
  • 20
  • 24