Search code examples
c++inheritancedesign-patternsoverriding

Multiple override-methods in inheritance each have multiple possible implementations


Let me introduce the following three classes: AbstractProcessor and these two child classes. The code below is not complex because there are only two child classes, but what if procedures1 and procedure2 both has many N candidate implementation? In such case, there are NxN child classes and a lot of duplication will be made by hand-coding. In the code below for example, each procedure can either be fast one or accurate one. So there are 2x2 possible child classes.

I would ask about technique/design pattern to reduce duplication. More precisely, is there any technique to reduce that NxN hand-coding to 2N hand-coding?

Noting that procedure1 and procedure2 both have to share the same var_ (in my case it is measurement value of physical world of robot) and the common function foo(), procedure1 and procudure2 can hardly be composed by a has-a relationship. Actually in my application, there are lot of var_ because the robot access to many type of sensors.

class AbstractProcessor
{
  virtual void procedure1() = 0;
  virtual void procedure2() = 0;

  Something foo(){ // ... 
  }
  double var_;

  void run(){
    procedure1();
    procedure2();
  }
};

class FastProcessor : public AbstractProcessor
{
  void procedure1() override {// ... fast procedure ( use foo and var_ inside)
  }
  void procedure2() override {// ... fast procedure ( use foo and var_ inside)
  }
};

class AccurateProcessor : public AbstractProcessor
{
  void procedure1() override {// ... accurate procedure ( use foo and var_ inside)
  }
  void procedure2() override {// ... accurate procedure ( use foo and var_ inside)
  }
};

Solution

  • Inheritance is not the solution to everything. Sometimes all the problems are gone once you don't use inheritance. There are many different ways to do what you want. One is to store the callables as members:

    #include <functional>
    #include <iostream>
    
    struct Processor
    {
      std::function<void(Processor*)> procedure1;
      std::function<void(Processor*)> procedure2;
    
      double var_ = 42.0;
      void foo() {
          std::cout << "hello foo\n";
      }
    
      void run(){
        procedure1(this);
        procedure2(this);
      }
    };
    
    int main() {
        Processor proc{
            [](auto p) { std::cout << p->var_ << "\n";},
            [](auto p) { p->foo(); }
        };
        proc.run();
    }
    

    Instead of lambdas the parameters to the constructor could be free functions so they can be more easily be reused. Note that I hade to make everything public in the class, in your example everything is private (it cannot work like that).

    As you are asking for a technique/design pattern, the term "composition over inheritance" fits best here I think. Dependency injection and other related design patterns might also help you to get into a different way of thinking about your design.