beginners architectural topic on c++ inheritance -
coming pure "c" i'm c++ novice , more or less new oo-development @ all, therefore apologize in advance "naive" view of topic below. in following tried describe problem in abstract style (my real classes different). code parts un-compilable, , should seen "thought" only.
i have several classes, inheriting base class:
class base { }; class derived1 : base { }; class derived2 : base { }; class derived3 : base { }; moreover, vector contains pointers instances of derived classes:
std::vector<base *> collection; now want provide class scheme usable other users. problem: when user iterates on collection, how he/she know concrete class type? providing virtual member functions derived classes not nice option, because don't know in advance , user wants do.
should he/she use dynamic_cast(...) obtain concrete class? not nice...
after hours of thinking ended following "solution", i'm not sure if real nice or total bullshit:
defining interface user object, operating on mentioned classes:
class derived1; class derived2; class derived3; class abstractuseroperation { virtual void call(derived1 * cl) = 0; virtual void call(derived2 * cl) = 0; virtual void call(derived3 * cl) = 0; }; the user defines concrete class, based on interface, realize his/her desired operation each possible type of derived classes:
class concreteuseroperation : abstractuseroperation { virtual void call(derived1 * cl) { ... } virtual void call(derived2 * cl) { ... } virtual void call(derived3 * cl) { ... } }; my own classes before, extended "evaluate":
class base { virtual void evaluate(abstractuseroperation* o) = 0; }; class derived1 : public base { void evaluate(abstractuseroperation *o) { o->call(this); } }; class derived2 : public base { void evaluate(abstractuseroperation *o) { o->call(this); } }; class derived3 : public base { void evaluate(abstractuseroperation *o) { o->call(this); } }; usage follows:
std::vector<base *> collection; concreteuseroperation o; // user defined class, doing whatever x x = collection[i]; x->evaluate(&o); // call user defined operation o on x of course, somehow "complicated", but, @ least, user defining concrete operation class, separated class scheme.
is approach acceptable architectural point of view ??? not boring experts here ;-)
many many thanks, michael
i'm not expert visitor concept, use similar code , think of callbacks. think, don't need define interface concreteuseroperation if allow calls derived's evaluate std::function callback argument. should able plug in lambdas visitors. samplecode:
#include <functional> struct base {}; struct derived : public base { void evaluate(std::function<void(const derived&)> callback) const { callback(*this); } int foo = 42; }; int main() { derived d; d.evaluate([](const derived& d){std::cout << d.foo << std::endl;}); } life example: http://coliru.stacked-crooked.com/a/223af4a43077a760
Comments
Post a Comment