C++ alternatives to preprocessor macro code generation? -
C++ alternatives to preprocessor macro code generation? -
i have collection of 50 small, similary structured classes derive mutual base. classes represent items read in file pairs of strings, first string used identify type of pair (which derived class should used represent data) , sec info itself. there visitor (as in visitor pattern) class associated derived classes , mill class generating appropriate derived class type identification string.
the setup looks this:
class nodeitemvisitor; // forwards declaration. class nodeitembase { public: std::string get_val() const { homecoming val; } virtual std::string idstr() const = 0; virtual void accept(nodeitemvisitor& v) = 0; private: std::string val; }; // forwards declarations of derived classes. class nodeitema; class nodeitemb; ... class nodeitemz; class nodeitemvisitor { public: virtual void visit(nodeitema& ni) = 0; ... virtual void visit(nodeitemz& ni) = 0; }; class nodeitema : public nodeitembase { public: virtual std::string idstr() const { homecoming "a"; } virtual void accept(nodeitemvisitor& v) { v.visit(*this); return; } }; ... class nodeitemz : public nodeitembase { public: virtual std::string idstr() const { homecoming "z"; } virtual void accept(nodeitemvisitor& v) { v.visit(*this); return; } }; class nodeitemfactory { public: // uses lookup table map input string 1 of "mkni" // functions below , calls it. static nodeitembase* mknifromid(const std::string& id); private: static nodeitembase* mknia(void) { homecoming new nodeitema(); } ... static nodeitembase* mkniz(void) { homecoming new nodeitemz(); } };
since code repetitive, takes lot of space, , since adding new item type require remembering add together lines in several places, using macros create derived classes , add together :
#define add_node_items \ add_node_item(a); \ ... add_node_item(z); #define add_node_item(id) \ class nodeitem##id : public nodeitembase \ { \ public: \ virtual std::string idstr() const { homecoming #id; } \ virtual void accept(nodeitemvisitor& v) { v.visit(*this); return; } \ } add_node_items #undef add_node_item class nodeitemvisitor { public: #define add_node_item(id) \ virtual void visit(nodeitem##id& ni) = 0; add_node_items #undef add_node_item }; class nodeitemfactory { public: // uses lookup table map input string 1 of "mkni" // functions below , calls it. static nodeitembase* mknifromid(const std::string& id); private: #define add_node_item(id) \ static nodeitembase* mkni##id(void) { homecoming new nodeitem##id(); } add_node_items #undef add_node_item }; #undef add_node_items
now question: using macros "compact" code "right" way this, or there more elegant/cleaner approach? comments suggesting alternative design welcome: i'm still pretty new object-oriented programming , don't have sense what's "right" yet.
thank much in advance!
you may want check out re-create of "modern c++ design," andrei alexandrescu, shows how automatically generate of code using c++ template system. alexandrescu dedicates 2 chapters visitor pattern , automatically generating class hierarchies, seems you're looking for. won't seek replicate code in answer, because it's dense, i'd wrong, , book has much improve explanation. :-)
c++
Comments
Post a Comment