Say you have a base class Dep
for a tree of classes. There is a virtual method Dep* Dep::create()
that I want to be implemented by every single leaf class. Is there any way to enforce this?
Note: The problem here is that there could be intermediate classes (say class B : public A : public Dep
) implementing this method (A::create
) by accident or because they think they are leaf classes, but are in fact subclassed themselves.
The question ends here.
If you are curious why I need this; I have a class Master
which has Dep
objects of unknown concrete type. If Master
is duplicated, I need to come up with a matching clone of the Dep
instance. Next best thing to do is the virtual constructor idiom, which introduces precisely this problem.
Additionally, I cannot even catch this (other then by crashing horribly), because for obscure reasons, people that have more to say than me, have outlawed dynamic_cast
in this project (perhaps this is a good decision; But anyways a completely different discussion).
Using curiously recurring template fun, you can achieve something quite similar:
template<typename T>
class Cloneable : public T, public Dep
{
private:
Cloneable<T>() : T() { }
public:
static Cloneable<T>* Create() { return new Cloneable<T>(); }
Cloneable<T>* clone() { return new Cloneable<T>(*this); }
};
Instead of deriving from Dep
and instantiating via new MyType
, use Cloneable<MyType>::Create
. Since Cloneable<MyType>
is derived from MyType
, you can use the instance the same way you would use any MyType
, except that it is now guaranteed to have Dep::clone
.
Additionally your Master
should not accept an instance of type Dep
, but enforce that it is a Cloneable<T>
. (Replace your orignial function by a simple function template that enforces this.) This guarantees that any Dep
inside the master has a correctly implemented clone
function.
Since Cloneable<MyType>
has no public constructor, it cannot be inherited, however your actual MyType
can be further inherited and used just as before.