On a project, I have the following problem :
I have a very simple inheritance scheme (I need inheritance and not composition) :
class Base
-> class DerivedA
-> class DerivedB
-> class DerivedC
A, B and C derive from Base and that’s all.
So now I have 2 choices :
public inheritance with virtuality
private inheritance without virtuality
For some optimization reasons (I need a lot of inlining) I don’t want virtuality … and I don’t want private inheritance. I think that the only option that remains is CRTP. But the base class have like 300 functions and implementing CRTP in it will be a real pain.
So I wonder if the following solution is valid : I use CRTP only in the destructor of the base class :
template<class TCRTP> class Base
{
~Base() {delete static_cast<TCRTP*>(this);}
}
where TCRTP will be DerivedA, B or C and I do public inheritance.
Is it perfectly ok, or problematic ?
Thank you very much.
Your destructor is definitely wrong. The destructor of a class does not and must not
deletethe memory for the object.What’s your objection to public inheritance without virtual functions? There are (at least) a couple of ways to prevent someone accidentally deleting a derived object through a base pointer. One is to make the base destructor
protected.Another is to stuff dynamically-allocated instances of the derived class straight into a
shared_ptr. This can even be ashared_ptr<Base>:Because
shared_ptrhas a template constructor that captures the type of its argument, theBase*pointer will be converted toDerivedA*in the deleter function associated with theshared_ptr, and hence deleted correctly. Nobody should ever be so daft as to try to extract a pointer out of ashared_ptrand delete it asBase*.Of course if you have no virtual functions, then the trick is only really useful when the only difference between the derived classes is what they set up in their constructors. Otherwise you’ll end up needing to downcast the
Base*pointer from theshared_ptr, in which case you should have used ashared_ptr<DerivedA>to begin with.