Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ way of dependency injection - Templates or virtual methods?

I wonder what is the C++ way of using dependency injection? Is that using templates or polymorphic classes? Consider the following code,

class AbstractReader
{
public:
  virtual void Read() = 0;
};

class XMLReader : public AbstractReader
{
public:
  void Read()  { std::cout << "Reading with a XML reader" << std::endl; }
};

class TextFileReader : public AbstractReader
{
public:
  void Read()  { std::cout << "Reading with a Text file reader" << std::endl; }
};

class Parser
{
public:
  Parser(AbstractReader* p_reader) : reader(p_reader) { }
  void StartParsing() { reader->Read();
    // other parsing logic
  }
private:
  AbstractReader* reader;
};

template<class T>
class GenericParser
{
public:
  GenericParser(T* p_reader) : reader(p_reader) { }

  void StartParsing()
  {
    reader->Read();
  }
private:
  T* reader;
};

1 - Which is the best method? GenericParser or Parser? I know if it is GenericParser, inheritance can be removed.

2 - If templates is the way to go, is it OK to write all the code in header files? I have seen many classes using templates writes all the code in header files rather than .h/.cpp combination. Is there any problems in doing so, something like inlining etc?

Any thoughts?

like image 395
Navaneeth K N Avatar asked May 31 '09 06:05

Navaneeth K N


1 Answers

You don't have a free choice in this, based on how you want to structure your code or header files. The answer is dictated to you by the requirements of your application.

It depends on whether the coupling can be be decided at compile time or must be delayed until runtime.

If the coupling between a component and its dependencies is decided permanently at compile time, you can use templates. The compiler will then be able to perform inlining.

If however the coupling needs to be decided at runtime (e.g. the user chooses which other component will supply the dependency, perhaps through a configuration file) then you can't use templates for that, and you must use a runtime polymorphic mechanism. If so, your choices include virtual functions, function pointers or std::function.

like image 117
Daniel Earwicker Avatar answered Nov 15 '22 14:11

Daniel Earwicker