Purushottam
Purushottam

Reputation: 624

Allocating base class object to a derieved class

Consider I am creating objects of two classes:

BaseClass B;
DerievedClass D;

and then i am doing:

B=D;
D=B;

Which is legal and why. This was a question asked by an interviewer of a C++ related Job. I know mostly B=D; will be valid (object slicing); but is it so that D=B; will only be valid if B has a default constructor? Yes, then why?

Upvotes: 2

Views: 107

Answers (3)

PierreBdR
PierreBdR

Reputation: 43234

Without seeing the implementation of the classes, you can't assume any of the two will compile!

First case: B=D

It will compile unless the = operator of B has been overloaded, in which case even B=B might be illegal. All you can say is that, if B=B is legal, then B=D is also legal, as D is a valid instance of the BaseClass class.

Second case: D=B

This one has been discussed properly by Nawaz. But in short, you need to explicitly allow it. You can either:

  1. Define the equal operator:

    DerivedClass::operator=(const BaseClass& copy)

  2. Define an explicit conversion operator:

    BaseClass::operator DerivedClass() const

  3. Add a constructor in DerivedClass that accepts a BaseClass:

    DerivedClass::DerivedClass(const BaseClass&)

Note that the second and third solutions should not co-existe, and the third one should generally be preferred. The conversion operator is there only in cases you can't modify the class or if you want to convert to a type that is not a class.

Upvotes: 0

grim
grim

Reputation: 143

Nawaz is right. B=D is legal because D is an instance of BaseClass and will be accepted through the compiler generated copy constructor of BaseClass.

BaseClass::BaseClass( const BaseClass& other ) { ... } // Implicit

This copy constructor will be inherited by DerivedClass, BUT when doing D=B then the compiler will look for a DerivedClass( const BaseClass& ) method, wich doesn't exist.

DerivedClass::DerivedClass( const DerivedClass& other ); // Implicit
DerivedClass::BaseClass( const BaseClass& other );       // Inherited
DerivedClass::DerivedClass( const BaseClass &other );    // Not defined!

Upvotes: 0

Sarfaraz Nawaz
Sarfaraz Nawaz

Reputation: 361302

B=D;
D=B;

First line will always compile. The second line may or may not compile, as it entirely depends on how you have written each class. The rest of the answer will shed light on it. Read on.


is it so that D=B; will only be valid if B has a default constructor?

No.

D=B will be valid only if D has defined operator= which takes B as argument.

Derived & operator=(const Base &base); //member of Derived

Base B;
Derived D;
D = B;     //allowed - assignment

Or if you do that in the initialization of D, then it will valid only if a constructor of D takes B as argument.

Derived(const Base &base); //a constructor of Derived

Base B;
Derived D = B; //allowed - initialization

Or B has defined a user-defined conversion to D.

operator Derived(); //member of Base

Base B;
Derived D = B; //allowed      - initialization
D = B;         //also allowed - assignment

Upvotes: 6

Related Questions