Using Factory pattern for parsing system I am currently trying to write a Parser system for my project. There are different type of files to be parsed (file1, file2, file3):

file1 -&gt; AData // stored in AData class using AParser class's parsing logic
file2 -&gt; BData // stored in BData class using BParser class's parsing logic
file3 -&gt; CData // stored in CData class using BParser class's parsing logic 


Files could be binary or txt. Different files require different logic for parsing because of the way file are written.

I have used a factory pattern for this purpose. The Base class is Parser which is an abstract class.

#include &lt;fstream&gt;
#include &lt;iostream&gt;
#include &lt;memory&gt;
#include &lt;string&gt;

// Base class
template &lt;class T&gt;
class Parser {
   public:
    virtual void DoParsing(T&amp;, std::ifstream&amp; fs) = 0;
};

// Base class for data
struct Data {};
//////
struct AData : Data {
    int data;
};

class AParser final : public Parser&lt;AData&gt; {
   public:
    void DoParsing(AData&amp; data, std::ifstream&amp; fs) {
    // implementation goes here
    }
};
///
struct BData : Data {
    char* data;
};

class BParser final : public Parser&lt;BData&gt; {
   public:
    void DoParsing(BData&amp; data, std::ifstream&amp; fs) {
    // implementation goes here
    }
};

template &lt;class T&gt;
class IParsing {
   public:
    void action(std::shared_ptr&lt;Parser&lt;T&gt;&gt; p, T d, std::ifstream&amp; fs) {
        p-&gt;DoParsing(d, fs);
    }
};

class FParsing {
   public:
    FParsing() {}

    void HandleParsing(std::string type, Data&amp; d, std::ifstream&amp; fs) {
      if (type == "AParsing") {
        std::shared_ptr&lt;IParsing&lt;AData&gt;&gt; iparse =
        std::make_shared&lt;IParsing&lt;AData&gt;&gt;();
        iparse-&gt;action(std::make_shared&lt;AParser&gt;(), static_cast&lt;AData&amp;&gt;(d),
               fs);
      } else if (type == "BParsing") {
        // iparse-&gt;action(std::make_shared&lt;BParser&gt;(), fs);
        std::shared_ptr&lt;IParsing&lt;BData&gt;&gt; iparse =
        std::make_shared&lt;IParsing&lt;BData&gt;&gt;();
        iparse-&gt;action(std::make_shared&lt;BParser&gt;(), static_cast&lt;BData&amp;&gt;(d),
               fs);

      } else {
        std::cout &lt;&lt; "Need shape\n";
      }
    }

   private:
};

int main() {
    std::ifstream iFile("data.txt");
    FParsing fparse;
    //AData is passed by ref because 
    // it will be populated during parsing process
    AData ad;
    fparse.HandleParsing("AParsing", ad, iFile);

    // BData
    BData ab;
    fparse.HandleParsing("BParsing", ab, iFile);
}


My questions are:


Do you think this is a right approach for creating a parsing system?
Is the factory pattern implementation correct?
I just wanted to make sure I am not making things more complex than it should be.
Are there other design patterns better than factory pattern for this purpose?
Design issues

You are unnecessarily restricting the Parser interface by forcing fs to be a std::ifstream&amp; when std::istream&amp; would work as well.
AParser::DoParsing(AData&amp;, std::ifstream&amp;) should be marked override. Same for BParser::DoParsing(BData&amp;, std::ifstream&amp;).
I can't see any specific purpose for IParsing: Why not call AParser::DoParsing or BParser::DoParsing directly?
Besides, parameter d of IParsing::action(std::shared_ptr&lt;Parser&lt;T&gt;&gt; p, T d, std::ifstream&amp; fs) should be of type T&amp;.
FParsing::HandleParsing(std::string, Data&amp;, std::ifstream&amp;) doesn't use any class instance members. Maybe make it static?
Also, parameter type from that function should probably be an enum - no need to use strings for that.
Why allocate two std::shared_ptr in case a valid parser is found if they won't be shared and will be deallocated once the function returns?
What advantage do you hope to get from this extravagant implementation over overloading operator&gt;&gt;(std::istream&amp;, AData&amp;) and operator&gt;&gt;(std::istream&amp;, BData&amp;) instead?