What I would like, if not with this syntax, but in spirit :
class A
{
virtual A f()=0;
};
class B : public A
{
B f();
};
I do see the problem with the code above : A is virtual, thus no instance of A can be created, hence no instance of A can be returned.
Yet, concrete subclasses of A (e.g. B) will have to implement the function f, which will always be able to return an instance of themselve (e.g. instance of B), i.e. an instance of a subclass of A.
While the above is incorrect and does not compile, is there a way to get something similar valid ? Possibly, but not necessarily, of the like:
class A
{
virtual "a concrete sublclass of A" f()=0;
};
note: I prefer not to return a pointer or a reference, as I would prefer B not to have to manage an instance of itself as attribute.
note: if possible c++11, but curious to hear about newer versions as well
Your attempted solution risks object slicing. Copying a B as an A will probably not work the way you expect. In general, it's best to avoid value semantics when dealing with polymorphic types. Consider returning a std::unique_ptr<A> instead :
#include <memory>
class A
{
public:
virtual std::unique_ptr<A> f()=0;
};
class B : public A
{
public:
std::unique_ptr<A> f() override;
};
This requires C++11. It will behave the way you expect and the user won't have to manage the lifetime of the resulting object.
However, contrary to what was shown in the original code, B::foo() won't give you access to the full interface of a B. It's not clear to me if this is required or not. If it is, you will need an extra layer. For example, define a g() that returns std::unique_ptr<B> which f() calls :
class B : public A
{
public:
std::unique_ptr<A> f() override { return g(); }
std::unique_ptr<B> g();
};
It looks like you're trying to write a factory or clone function of sorts. This is commonly done using std::unique_ptr to cleanly pass ownership of the created object to the caller:
class A
{
virtual std::unique_ptr<A> f() = 0;
};
class B : public A
{
std::unique_ptr<A> f() override;
};
Demo
The only downside is that you cannot have B::f return a std::unique_ptr<B> as that's not covariant with std::unique_ptr<A> (even though it implicitly converts to it).
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