I would like to force a certain API for all classes derived from the base class. Normally, you do that using an abstract base class that has purely virtual functions. However, how do you handle functions that return the derived type? How do I go about forcing that type of function?
struct base
{
virtual base func() = 0;
};
struct deriv1 : base
{
deriv1 func();
};
struct deriv2 : base
{
deriv2 func();
};
This example will give an error like "invalid abstract return type for member function". I've seen some answers that suggest returning pointers, but I don't particularly want to dip into dynamic memory for that and keeping track of all the allocated pointers would be a special kind of hell. Any ideas?
In your example, the
func
won't be "the same function", so thederiv1
andderiv2
variants won't have a different virtual function.Unfortunately, there is no other alternative than to return a pointer - it doesn't have to be a pointer to dynamically allocated memory (you could for example return a pointer to
this
or astatic deriv2 anObject;
- but it needs to be a pointer tobase
. [Or a reference, but the same problem applies].The main reason for this (aside from the fact that "functions can't be differentiated only on return type") is that if you have some generic code that looks something like this:
Now, either you have now cut off [sliced] your
deriv1
orderiv2
into the size of abase
, or you'd have copied an object that is larger thanbase
into abase
-size object - neither of which will be of any benefit whatsoever. [I'm assuming that in the REAL use-case for this,deriv1
andderiv2
are in fact different frombase
by more aspects than the name of the object - otherwise, it's quite pointless. And thatderiv1
andderiv2
are inheriting frombase
, of course].In other words, you can't copy an object of unknown type with
=
. And it's absolutely no point in having a virtual function if you have to know what type it returns.When a virtual function returns a pointer or reference to a class, a class which inherits from the base class and overrides the function is allowed to change the return type to a pointer or reference to a class which is derived from the original return type.
You can't return base by value as it is abstract so you can't actually create one by itself.
http://en.wikipedia.org/wiki/Covariant_return_type
When using virtual functions and base classes, you usually have to use dynamic allocation to create your objects. I suggest you look into smart pointers to help manage the memory.
Basically a way of saying "If you want to replace deriv1 with deriv2 in your code, you need to implement these functions"
From your quote here above, it looks like you want something like this:
You'll see that this holds true to your quote. D2 replaces D1 seamlessly from the perspective of driver...