C ++ dependency injection method - Templates or virtual methods?

I wonder what is C ++ - a way to use dependency injection? Is it using patterns 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 - What is the best method? GenericParser or Parser? I know if this is a GenericParser, inheritance can be removed.

2 - If templates are the way to go, is it okay to write all the code in the header files? I have seen that many classes using templates write all the code in the header files, rather than the .h / .cpp combination. Are there any problems with this, something like insertion, etc.

Any thoughts?

+3
source share
4 answers

, , . .

, .

, . inlining.

, , (, , , , ), , , , , std::function.

+9

, , , , . , , . , cpp, , , , . , , .

+2

1. "" . . , ( ), . , ( ). .

, . , , . , , , ( ), .

2 1. , , . . Inlining ; , , , .

0

GenericParser Parser?

, , , .
... boost:: function and boost:: lambda. , , - function ( ) . boost::function< void ()> reader = bind( &TextFile::read, reader ); .

class User
{
const boost::function< void ()>& reader;

public:
    void setReader( const boost::function< void ()>& reader ) 
    : reader(reader) {
    }
};

, .h/.cpp.

, , (Comau-). "" 1 "" 2


@CiscoIPPhone Comment: The problem with the shared parser is that the class you are about to enter must also be a template.

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

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

// Now you have a GeniricParser Interface but your Parser is only usable for 
// TextFileReader 
class Parser
{
public:
    Parser( GenericParser<TextFileReader> p_reader) : reader(p_reader) { }
    void StartParsing() { 
        reader->Read();
    }
private:
    GenericParser<RealParser> reader;
};


//Solution is to make Parser also a template class
template<class T>
class Parser
{
public:
    Parser( GenericParser<T> p_reader) : reader(p_reader) { }
    void StartParsing() { 
        reader->Read();
    }
private:
    GenericParser<T> reader;
};
0
source

Source: https://habr.com/ru/post/1709459/


All Articles