using namespace boost;
class A {};
class B : public A {};
class X {
virtual shared_ptr<A> foo();
};
class Y : public X {
virtual shared_ptr<B> foo();
};
The return types aren't covariant (nor are they, therefore, legal), but they would be if I was using raw pointers instead. What's the commonly accepted idiom to work around this, if there is one?
I think that a solution is fundamentally impossible because covariance depends on pointer arithmetic which is incompatible with smart pointers.
When Y::foo
returns shared_ptr<B>
to a dynamic caller, it must be cast to shared_ptr<A>
before use. In your case, a B*
can (probably) simply be reinterpreted as an A*
, but for multiple inheritance, you would need some magic to tell C++ about static_cast<A*>(shared_ptr<B>::get())
.
Not directly, but you can fake it by making the actual virtual functions inaccessible from outside the class and wrapping the virtual function call into a non-virtual function. Downside is that you'll have to remember to implement this wrapper function on each derived class. But you could get around this by puting both the virtul function declaration and the wrapper into the macro.
using namespace boost; // for shared_ptr, make_shared and static_pointer_cast.
// "Fake" implementation of the clone() function.
#define CLONE(MyType) \
shared_ptr<MyType> clone() \
{ \
shared_ptr<Base> res = clone_impl(); \
assert(dynamic_cast<MyType*>(res.get()) != 0); \
return static_pointer_cast<MyType>(res); \
}
class Base
{
protected:
// The actual implementation of the clone() function.
virtual shared_ptr<Base> clone_impl() { return make_shared<Base>(*this); }
public:
// non-virtual shared_ptr<Base> clone();
CLONE(Base)
};
class Derived : public Base
{
protected:
virtual shared_ptr<Base> clone_impl() { return make_shared<Derived>(*this); }
public:
// non-virtual shared_ptr<Derived> clone();
CLONE(Derived)
};
int main()
{
shared_ptr<Derived> p = make_shared<Derived>();
shared_ptr<Derived> clone = p->clone();
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With