I am trying to implement a Controller
class for two systems. Each Controller
uses a Solver
class instance.
I already have two Solver
class implementations:
class AbstractSolver { virtual void func() = 0; };
class System1Solver : AbstractSolver { void func() override; };
class System2Solver : AbstractSolver { void func() override; };
The Controller
implementation is the same for both Solver
types. I could implement both Controller
classes like...
class System1Controller {
public:
System1Controller(System1Solver solver);
System1Solver solver;
void func() { solver.func(); };
};
class System2Controller {
public:
System2Controller(System2Solver solver);
System2Solver solver;
void func() { solver.func(); };
};
I'd like to not copy and paste the same code. Both System?Controller
implementations are identical, except for the type of solver
. Can I instead use templates somehow to achieve code re-use?
template <class SolverClass>
class Controller {
public:
Controller(SolverClass solver);
SolverClass solver;
void func() { solver.func(); };
};
class System1Controller : Controller<System1Solver>;
class System2Controller : Controller<System2Solver>;
Edit: This example actually works. Thanks everyone for confirming this was an appropriate way to accomplish this.
/* Compile with g++ -O3 -std=c++14 -o crimes metaprogramming_crimes.cpp */
#include <iostream>
class AbstractSolver { virtual void func() = 0; };
class System1Solver : AbstractSolver { public: void func() override { }; };
class System2Solver : AbstractSolver { public: void func() override { }; };
/*
class System1Controller {
public:
System1Solver solver;
void func() { solver.func(); };
};
class System2Controller {
public:
System2Controller(System2Solver solver);
System2Solver solver;
void func() { solver.func(); };
};
*/
template <class SolverClass>
class Controller {
public:
SolverClass solver;
void func() { solver.func(); };
};
class System1Controller : Controller<System1Solver> { };
class System2Controller : Controller<System2Solver> { };
auto main()->int {
System1Controller controller1;
System2Controller controller2;
if (typeid(controller1) != typeid(controller2)) {
std::cout << "Yay!" << std::endl;
} else {
std::cout << "Boo." << std::endl;
}
};
Another option is to use polymorphism: keep a pointer to your AbstractSolver
in the single Controller
class, and pass appropriate concrete solver to the controller's constructor.