interface - c++ A factory with initialisation of the product after creation -


i want have factory creation of handle object client, defined interface handle classes, faced difficulty client have initialize after creation of handle object. problem initialization depends on handle type.

the best can code below, in implementation, client can initialize wrong data type. try deal problem using template can't find solution.

how can deal problem of initialization? maybe factory not best way?

#include <iostream> #include <map> #include <vector> #include <string>  // type erasure data type use in handle class class handledatatype { public:     handledatatype() : datatype("notype") {};     handledatatype(std::string s) : datatype(s) {}; public:     std::string datatype; }; class handledatatypeint : public handledatatype //simplify data type {     int data; public:     handledatatypeint(int a) : data(a), handledatatype("int")  {}; }; class handledatatypedouble : public handledatatype //simplify data type {     double data; public:     handledatatypedouble(double a) : data(a),  handledatatype("double")  {}; };  //class prototype  template <class t> class prototype { public:     virtual ~prototype(){}       virtual t* clone() const =0 ; };  class handlei : public  prototype<handlei> {     //attribute private:     unsigned int        m_id;     std::string         m_handletype;     std::string         m_name;     handledatatype*     m_data;//m_data type depends of handlei subclass  public:     //constructor     handlei() {};     handlei(std::string type) : m_handletype(type) {};     handlei(std::string type, unsigned int id, std::string name) : m_handletype(type), m_id(id), m_name(name) {};     ~handlei() {};      //get     std::string     get_handletype() const {return m_handletype;};     std::string     get_handlename() const {return m_name;};     unsigned int    get_handleid()   const {return m_id;};     handledatatype* get_data()       const {return m_data;};      // set     void        set_name(const std::string name)    {m_name=name;};     void        set_id(const unsigned int id)       {m_id=id;};     void        set_data(handledatatype & d)        {m_data=new handledatatype(d);};      //  virtual method if interface public:     virtual void            precompute() =0;     virtual void            compute() =0; }; // handle interface class handleint : public handlei { public:     // constructor;     handleint() : handlei("handleint") {};     handleint(unsigned int id, std::string name) : handlei("handleint", id, name) {};     ~handleint() {};      // implementation of virtual method public:     // clone method prototype fabric     handlei*        clone() const   {return new handleint(*this);}     // inteface method     void            precompute()    {std::cout<< "precomputeint" << std::endl;}     void            compute()       {std::cout<< "computeint" << std::endl;} };   class handledouble : public handlei { public:     // constructor;     handledouble() : handlei("handledouble") {};     handledouble(unsigned int id, std::string name) : handlei("handledouble", id, name) {};     ~handledouble() {};      // implementation of virtual method public:              // clone method prototype fabric     handlei*        clone() const   {return new handledouble(*this);}     // inteface method     void            precompute()    {std::cout<< "precomputedouble" << std::endl;}     void            compute()       {std::cout<< "computedouble" << std::endl;} };  class factoryhandle { private :     std::map<std::string, handlei*> m_handlereference;  public :     factoryhandle()     {         m_handlereference["int"] = new handleint() ;         m_handlereference["double"] = new handledouble() ;     }     handlei* createhandle(std::string htype)     {         return m_handlereference[htype]->clone();     }     ~factoryhandle()     {         std::map<std::string, handlei*>::iterator it;         (it=m_handlereference.begin(); it!=m_handlereference.end(); ++it)             delete it->second;         m_handlereference.clear();     } };  int main() {     handledatatypeint * dataint = new handledatatypeint(1);     handledatatypedouble * datadouble = new handledatatypedouble(1.0);      factoryhandle* fh = new factoryhandle() ;     handlei *   hint = fh->createhandle("int");     // initialise handle hint     hint->set_id(1);     hint->set_name("test_int");     hint->set_data(*dataint);     //     std::cout << hint->get_handletype() << std::endl;     std::cout << hint->get_handleid() << std::endl;     std::cout << hint->get_handlename() << std::endl;     hint->compute();     std::cout << hint->get_data()->datatype << std::endl;       // client can initialize data of wrong type     //hint->set_data(*datadouble); -> won't authorise such initalisation     hint->set_id(1);     hint->set_name("test_int");     hint->set_data(*datadouble);     //     std::cout << hint->get_handletype() << std::endl;     std::cout << hint->get_handleid() << std::endl;     std::cout << hint->get_handlename() << std::endl;     hint->compute();     std::cout << hint->get_data()->datatype << std::endl; // have here double data type!!! } 


Comments