i want have class creates different sorts of objects based on string pass it. research, best describes factory design pattern. having success implementing it, i've run design issue: don't know how create objects different length constructors.
let's take example, abstract parent class called pet. 3 children: fish, cat, , dog. inherit weight , color pet, goes in constructors. fish might want number of fins , boolean regarding whether saltwater fish. that's 4 parameter constructor. cat number of legs. that's 3 parameters. dog might have parameters legs, breed, , whether plays other dogs, 5 parameters.
in c++, understand there isn't reflection, common practice seems to declare map of string function pointers, function pointer points function looks this:
template<typename t> pet* createobject(int weight, std::string color) {return new t(weight, color);} again, i'm not sure how stuff more parameters call without affecting calls of other objects' constructors.
i can think of 2 workarounds: make new functions accept different amount of parameters or make default parameters constructors above size.
workaround 1 seems kind of excessive depending on how many different parameter sizes have.
workaround 2 seems disregard entire point of constructor, forced assign data after calling constructor.
are there other better workarounds?
you can use variadic templates , perfect forwarding.
template<typename t, typename... args> pet* createobject(args&&... args) { return new t(std::forward<args>(args)...); } however, since pointer can converted base class, better if function returns t*. moreover, using naked pointers not wise, you'll have delete them manually. it's better use shared_ptr or unique_ptr. these classes there similar factory methods: make_shared , make_unique (the latter in c++14). or, if compiler doesn't support c++11, can use shared_ptr , make_shared boost.
of course solution works when know @ compile time type you'll need create. if have decide @ runtime, whole problem has considered different direction, if don't know type going create, there no way can know parameters give them, except parameters common types. in case need abstract factory pattern. fortunately, c++ (at least c++11) provides way implement pattern without creating hell lot of classes. example, let's have create instances of class derived pet. actual kind of pet, size , other attributes decided somewhere else, while name of pet decided @ time of creation. then, you'll need factory this:
typedef std::function<std::shared_ptr<pet>(const std::string& name)> petfactory; at point decide want create dog (i leave meaning of actual creation parameters imagination).
petfactory petfactory = [](const std::string& name) { return std::make_shared<dog>(name, 12, "brown", 23.5); } when create it, need call factory:
std::shared_ptr<pet> pet = petfactory("pet name");
Comments
Post a Comment