C++ Polymorphism and type specifics

76 views Asked by At

I need have classes which implement similar things (different types of neural networks), but with somewhat different interfaces.

Doing research, I want to run the program with different neural network in the composing class. I want to be able to substitute and of existing types. It would be nice to handle this by run-time start up parameter, but compile-time placement would work as well.

I see at least 5 approaches with their drawbacks which stops me from using them:

  1. Implement base class with virtual functions and place pointer to base class into composing class. Main drawbacks: risks of object slicing, hell of cloning functions, assignment and comparison operators for the derived classes, dynamic_cast or similar dirty tricks to identify real object type for apply type-specific functions.
  2. Use template for neural network type. Drawback: this will require most of code to be moved to templates and, as the result I will have to put lots of implementation code into header files.
  3. Unify interfaces by adding placeholder functions. Drawback: interfaces will become dirty hell.
  4. Use C++ preprocessor with #ifdef blocks to separate two versions of code. Drawback: it is dirty copy/paste of blocks of code and with more than 2 classes comes to hell.
  5. Use adapter pattern which will provide unified interface and hide the details. Drawback: actually, it will be implemented with the pointer to implementation, so will suffer both from (1) and (2), but (2) will be only in adapter interface.

Are there better ways in the modern C++ to implement this? Something tells me that I can build some kind of solution around blocks constructed with std::function, but I am not sure yet.

1

There are 1 answers

0
Damir Tenishev On

Well, I found the solution, really don't know why I blundered yesterday, overcomplicating things.

The solution works for compile time. For run-time I would use option (1) from the original question.

The overall idea is to have overloaded functions with parameters of the specific classes which will allow compile-time polymorphism to choose the correct function which will take correct type to setup, tune, etc.

Solution

class NNType1 { … };
class NNType2 { … };

using NeuralNetwork = NNType1;
// using NeuralNetwork = NNType2;

class Creature {
    NeuralNetwork nn;
public:
  template <typename T> void setupNN(NNType1&);
  template <typename T> void tuneNN(NNType1&);
};

template<> Creature::setupNN(NNType1& nn) {
…
}

Actually instead of overloaded functions, the templates are used to simplify class declaration avoiding the list of overloaded functions for all types.

Now all the code which uses custom part of interfaces is put into these setupNN/tuneNN functions which are specific to concrete classes NNType1/NNType2/etc. For the generic code of Creature these functions hide implementation details.

Profits

  1. Easy to implement
  2. Now code is split into small functions without if/switch
  3. No RTTI information used, no dynamic_casts, etc.

Any comments, corrections, improvement suggestions?