10

A derived class object can be assigned to a base class object in C++.

Derived d;
Base b = d; // It's Ok

But why can't a base class object be assigned to a derived class object?

Base b;
Derived d = b; //Not Ok. Compiler give an error

Edit:

Sorry, but this question was actually asked durring an interview.

scopchanov
  • 7,966
  • 10
  • 40
  • 68
msc
  • 33,420
  • 29
  • 119
  • 214
  • 4
    Because it would make absolutely no sense. Or maybe you could explain why you think it should be possible, and what the result of such an action should be. – juanchopanza Aug 24 '17 at 09:28
  • @juanchopanza Actually this question asked in interview. – msc Aug 24 '17 at 09:30
  • Tell us what you think should happen for `Derived d = b;` – M.M Aug 24 '17 at 09:31
  • 2
    In "Introduction to OOP" terms: every apple is a fruit, but not every fruit is an apple. – molbdnilo Aug 24 '17 at 09:32
  • 1
    @rsp Thinking about what the outcome woudl be is a good way to reach the conclusion that it makes no sense :-) I guess that's what the interviewers want to trigger. (not my down-vote BTW.) – juanchopanza Aug 24 '17 at 09:33
  • 5
    An obvious question is no necessary a poor question. Please don't downvote on the subjective grounds of obviousness. This question is clearly posed. – Bathsheba Aug 24 '17 at 09:33

5 Answers5

10

Inheritance is an "is-a" relationship, but it's one-way only.

If you have e.g.

struct Base { /* ... */ };
struct Derived : Base { /* ... */ };

Then Derived is a Base, but Base is not a Derived.

That's why you can assign or initialize a base-class instance with a derived object (but beware of object slicing), but not the other way around.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
10

A derived object is a base object, with additional information.

You can initialize a complete base object from the base part of a derived object, no problem.

But if you want to construct a derived object from just a base object, what should the additional information be initialized with?

If you want to provide defaults for that additional information, you can do so by declaring a Derived(Base const &) constructor. But since it does not work in the general case, it isn't done for you.

Quentin
  • 62,093
  • 7
  • 131
  • 191
  • 1
    This should be accepted answer. All those "because a is b b is not a" doesn't really explain anything. – lineil Sep 13 '18 at 20:35
3

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.

That said, you can handcode such a possibility by an appropriate overload of the assignment operator and an appropriate constructor in the derived class.

Aside from perhaps overcomplicating the language, I don't see why a trivially copyable base class instance could not be assigned to a derived class that contains no additional members. But this is not implemented in any C++ standard at the time of my writing. Furthermore, to my mind at least, the consequence of having any uninitialised derived class members and bypassed derived class constructors doesn't require materially more consideration on the part of a programmer than the perils of object slicing if a derived class instance is assigned to a base class! In other words, I don't think the hackneyed retort "because it makes no sense" makes much sense in itself.

Reference: http://en.cppreference.com/w/cpp/types/is_trivially_copyable

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
2

If there is a public inheritance b/w Base and Derived class , then that is ‘is a’ relationship .

And in “is a” Relationship Derived is a Base .

One of the most importance point here is that “is a Relation ” is not bi-directional.

I.e. Derived is a Base But Base is not Derived.

Let say we have two classes Shape and Circle.

Shape is a Base and Circle is publically Inherited from Shape.

so, Circle is a Shape But Shape is not Circle

//main.cpp
#include <iostream>
#include <string>

using namespace std;

class Shape
{
private:
    int x;
public:
    Shape(int i):x{i}
    {
        cout << "Base constructor called " << endl; 
    }
};

class Circle : public Shape
{
private :
    string color;  
public : 
    Circle(int radius) : Shape{ radius } 
    {
        cout << "Derived constructor called " << endl;
    }
    Circle(int radius, string color) : Shape{ radius }, color{ color }  
    {
        cout << "Derived constructor called " << endl;
    }
};


int main()
{
    //This is valid .  since a circle is a shape 
    Circle s(1);
    Shape a = s;

    return 0; 
} 

But you can't do this since a Shape is not a circle And inheritance is not Bi Directional here

 Shape s(1);
 Circle a = s;

If you do this you will get a compiler error

  no suitable user-defined conversion
        from "Shape" to "Circle" exists
Hamza.S
  • 1,319
  • 9
  • 18
-2

How about using a temporary reference?

Base b;
Derived d;
Base & d_ref = d;
d_ref = b;
Tim
  • 403
  • 4
  • 9
  • 1
    This doesn't answer the question. – flau Dec 18 '18 at 13:34
  • Technically, it doesn’t answer the original question. I thought of it as an answer to a similar, and very practical question, “_How_ can a Base class object be assigned to a Derived class object?” This is how I found this thread, and I could not find an answer elsewhere. – Tim Dec 19 '18 at 14:08