In C++ we can do this:
struct Base
{
virtual Base* Clone() const { ... }
virtual ~Base(){}
};
struct Derived : Base
{
virtual Derived* Clone() const {...} //overrides Base::Clone
};
However, the following won't do the same trick:
struct Base
{
virtual shared_ptr<Base> Clone() const { ... }
virtual ~Base(){}
};
struct Derived : Base
{
virtual shared_ptr<Derived> Clone() const {...} //hides Base::Clone
};
In this example Derived::Clone
hides Base::Clone
rather than overrides it, because the standard says that the return type of an overriding member may change only from reference(or pointer) to base to reference (or pointer) to derived. Is there any clever workaround for this? Of course one could argue that the Clone
function should return a plain pointer anyway, but let's forget it for now - this is just an illustratory example. I am looking for a way to enable changing the return type of a virtual function from a smart pointer to Base
to a smart pointer to Derived
.
Thanks in advance!
Update: My second example indeed doesn't compile, thanks to Iammilind
You can't do it directly, but there are a couple of ways to simulate it, with the help of the Non-Virtual Interface idiom.
struct Base
{
private:
virtual Base* doClone() const { ... }
public:
shared_ptr<Base> Clone() const { return shared_ptr<Base>(doClone()); }
virtual ~Base(){}
};
struct Derived : Base
{
private:
virtual Derived* doClone() const { ... }
public:
shared_ptr<Derived> Clone() const { return shared_ptr<Derived>(doClone()); }
};
This only works if you actually have a raw pointer to start off with.
struct Base
{
private:
virtual shared_ptr<Base> doClone() const { ... }
public:
shared_ptr<Base> Clone() const { return doClone(); }
virtual ~Base(){}
};
struct Derived : Base
{
private:
virtual shared_ptr<Base> doClone() const { ... }
public:
shared_ptr<Derived> Clone() const
{ return static_pointer_cast<Derived>(doClone()); }
};
Here you must make sure that all overrides of Derived::doClone
do actually return pointers to Derived
or a class derived from it.