in c++11 standard, if class B inherits from class A, then 'B is an A'. However, i am still confused regarding this notion: look at this code:
class Base {
public:
virtual ~Base() {}
virtual Base* clone() const = 0;
};
class Derived : public Base {
public:
virtual Base* clone() const {
return new Derived(*this);
}
//<more functions>
};
we returned a pointer to Base from Derived, but if using this approach in this code:
Derived* d1 = new Derived();
Derived* d2 = d1->clone();
what we did is assigning Base*
in Derived*
!!
The Problem:
why this code does not compile? How could it be modified(and why?) in order to fit with the inheritance?
The code you posted will not compile even after some trivial edits (which I made). The signature of the Derived::clone()
should be:
virtual Derived* clone() const override { // <-- return type
return new Derived(*this);
}
Even though the return type of clone()
in Base
and Derived
class are different, it's a valid overriding of virtual
function because, the co-variance is legal in C++.
There won't be any slicing when you deal with the pointers as stated in your question.
Derived::clone()
should return Derived*
.
Whether the clone()
should be virtual
or not depends on the design, but with virtual
destructor it's a good idea.
Another approach is to use a template
and avoid virtual
:
class Base {
public:
virtual ~Base() {}
template<class T> // now need not add this trivial code in all derived classes
T* clone() const { return new T(*this); }
};