Home > Net >  Provide different functionality with subclasses
Provide different functionality with subclasses

Time:03-21

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.

  •  Tags:  
  • c
  • Related