Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is an assignment to a base class valid, but an assignment to a derived class a compilation error?

This was an interview question. Consider the following:

struct A {};  struct B : A {};  A a;  B b;  a = b; b = a;  

Why does b = a; throw an error, while a = b; is perfectly fine?

like image 560
maxpayne Avatar asked Jul 01 '11 15:07

maxpayne


People also ask

Why a base class pointer can point to its derived class object but a derived class pointer Cannot point to its base class object?

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.

What is the problem with the legal assignment of a derived class object to a base class variable?

In general a C++ compiler will disallow the assignment of a object of a base class to a derived one as, in a sense, the derived class is a superset of the base class: i.e. it wouldn't know how to to deal with any members that are specific to the derived class.

What is the difference between a base class and a derived class?

The class whose members are inherited is called the base class, and the class that inherits those members is called the derived class. A derived class can have only one direct base class.

Can derived class objects be assigned to base class?

Object Slicing in C++ In C++, a derived class object can be assigned to a base class object, but the other way is not possible.


2 Answers

Because the implicitly declared copy assignment operator of B hides the implicitly declared copy assignment operator of A.

So for the line b = a, only the the operator= of B is a candidate. But its parameter has type B const&, which cannot be initialized by an A argument (you would need a downcast). So you get an error.

like image 107
Johannes Schaub - litb Avatar answered Oct 12 '22 02:10

Johannes Schaub - litb


Because every B is an A, but not every A is a B.

Edited following comments to make things a bit clearer (I modified your example):

struct A {int someInt;};  struct B : A {int anotherInt};  A a;  B b;   /* Compiler thinks: B inherits from A, so I'm going to create    a new A from b, stripping B-specific fields. Then, I assign it to a.    Let's do this!  */ a = b;  /* Compiler thinks: I'm missing some information here! If I create a new B    from a, what do I put in b.anotherInt?    Let's not do this!  */ b = a; 

In your example, there's no attributes someInt nor anotherInt, so it could work. But the compiler will not allow it anyway.

like image 44
user703016 Avatar answered Oct 12 '22 02:10

user703016