I don't know if this title is descriptive enough... but I have no idea what else to call it. What I'm trying to do is the following:
There is a class (lets call it the AgentClass
) that consumes the functionality of some other class (in this example the Initializer
). I have different versions of Initializer
(like ZeroInit, RandomInit, OptimisticInit) that inherit from a common base class.
How would I best implement this system, so that when the 'AgentClass' gets instantiated, I will be able to specify which type of Initializer
I get? I was thinking of templates... but does this work on the level of classes as typenames? Additionally I think the methods provided by the Initializer
can be static. How does that affect the implementation?
Here is some code:
//base_init.h
class BaseInit
{
public:
virtual init(double** data) = 0;
}
//zero_init.h
#include "base_init.h"
class ZeroInit : BaseInint
{
init(double** data) override;
}
//random_init.h
#include "base_init.h"
class RandomInit : BaseInint
{
init(double** data) override;
}
//agent_class.cpp
#include "base_init.h"
#include "zero_init.h"
#include "random_init.h"
class AgentClass
{
private:
double** data;
public:
AgentClass()
{
BaseInit* init = new ZeroInit(); // Problem here: ZeroInit is "hard coded". I would like this to be specified as constructor argument or template for AgentClass
init.init(data);
}
}
CodePudding user response:
Roughly speaking you have two options: Choose at runtime which derived class to use, then you can pass the instance as parameter to the constructor:
AgentClass(BaseInit& init)
{
init.init(data);
}
Or select at compile time which derived class to use. When it is ok that eg AgentClass<RandomInit>
is a different type than AgentClass<ZeroInit>
then you can make AgentClass
a class template:
template <typename Init>
class AgentClass {
private:
double** data;
public:
AgentClass() {
Init{}.init(data);
}
}
In this case there is no need for BaseInit
. The different parameters for Init
can be completely unrelated types, as long as they provide an init
method. Also in this case init
can be a static function, so you need not create an instance of Init
. With inheritance that isnt an option because you cannot override static methods in derived classes.
As mentioned in a comment by molbdnilo, if the xInit
classes have no state and consist of a single method, then you do not need the classes in the first place. All you need is a function void(double**)
. You could pass a function pointer to a free function to the constructor for example.