Reputation: 624
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
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:
Define the equal operator:
DerivedClass::operator=(const BaseClass& copy)
Define an explicit conversion operator:
BaseClass::operator DerivedClass() const
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
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
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