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
Post a Comment