I have a hierarchy of classes for which I want to use polymorphism to call the correct member functions.
On a basic level this works, but I encountered a problem when trying to use a Mixin class to extend or change the functionality of some class.
Basically, I want to do some validation on a member value when constructing an object that inherits from the mixin.
(I am coming from a python background, where it is easy to create mixins that alter the constructor behaviour. The method resolution order guarantees that functions called from the constructor are called from the derived class first)
In C++ dynamic binding is disabled in constructors (I understand the reasons). A call to a virtual void init()
function would not work, since always the Base class function would be called.
Is there any way to guarantee that the validate()
function is executed without needing to explicitly define the constructors again?
Factories would be one method, but I also want to have constructors with different type parameters.
A minimal example is shown below.
Thanks in davance
class Base
{
Base(){};
//... some virtual functions...
}
class Derived: public Base
{
using Base::Base;
// new constructors
Derived(some pars){};
Derived(other pars){};
//... some virtual functions...
}
template <class B>
class Mixin: public B
{
using B::B;
Mixin()
{
// mixin related constructor code
// maybe some member validation or discretization of a continuous value
// hides B::B(), but is only called if the default constructor is called, not for B::B(pars)
this->validate();
}
void validate(){};
}
class UsingMixin: public Mixin<Derived>
{
using Mixin::Mixin; // inherit all constructors
// I want to avoid defining the same constructors from Derived again,
// since there would be no change
// some functions
}
EDIT: One way to achieve this would be to have templated constructors on the mixin, but I don't know about the safety and usability of this approach, since I would need to know about the maximum number of constructors parameters from the base class.
template <class B>
class Mixin: public B
{
template <class Arg0>
Mixin(Arg0 arg0)
: B(arg0)
{
this->validate();
}
template <class Arg0, class Arg1>
Mixin(Arg0 arg0, Arg1 arg1)
: B(arg0, arg1)
{
this->validate();
}
template <class Arg0, class Arg1, class Arg2>
Mixin(Arg0 arg0, Arg1 arg1, Arg2 arg2)
: B(arg0, arg1, arg2)
{
this->validate();
}
template <class Arg0, class Arg1, class Arg2, class Arg3>
Mixin(Arg0 arg0, Arg1 arg1, Arg2 arg2, Arg3 arg3)
: B(arg0, arg1, arg2, arg3)
{
this->validate();
}
void validate(){}
}