C++ alternatives to preprocessor macro code generation?
<p>I have a collection of about 50 small, very similary structured classes that
all derive from a common base.  The classes represent items that are read in
from a file as pairs of strings, where the first string is used to identify the
type of the pair (which derived class should be used to represent the data) and
the second is the data itself.  There is also a visitor (as in visitor pattern)
class associated with the derived classes and a factory class for generating
the appropriate derived class from the type identification string.</p>

<p>The setup looks something like this:</p>

<pre><code>class NodeItemVisitor;  // Forward declaration.

class NodeItemBase
{
    public:
      std::string get_val() const { return val; }
      virtual std::string idstr() const = 0;
      virtual void accept(NodeItemVisitor&amp; v) = 0;

    private:
      std::string val;
};

// Forward declarations of derived classes.
class NodeItemA;
class NodeItemB;
...
class NodeItemZ;

class NodeItemVisitor
{
    public:
        virtual void visit(NodeItemA&amp; ni) = 0;
        ...
        virtual void visit(NodeItemZ&amp; ni) = 0;
};

class NodeItemA : public NodeItemBase
{
    public:
        virtual std::string idstr() const { return "A"; }
        virtual void accept(NodeItemVisitor&amp; v) { v.visit(*this); return; }
};

...

class NodeItemZ : public NodeItemBase
{
    public:
        virtual std::string idstr() const { return "Z"; }
        virtual void accept(NodeItemVisitor&amp; v) { v.visit(*this); return; }
};

class NodeItemFactory
{
    public:
        // Uses a lookup table to map the input string to one of the "mkni" 
        // functions below and then calls it.
        static NodeItemBase* mknifromid(const std::string&amp; id);

    private:
        static NodeItemBase* mkniA(void) { return new NodeItemA(); }
        ...
        static NodeItemBase* mkniZ(void) { return new NodeItemZ(); }
};
</code></pre>

<p>Since this code is very repetitive, takes up a lot of space, and since adding a
new item type would require remembering to add lines in several places, I am
using macros to create the derived classes and to add :</p>

<pre><code>#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 { return #ID; } \
        virtual void accept(NodeItemVisitor&amp; 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&amp; ni) = 0;
    ADD_NODE_ITEMS
#undef ADD_NODE_ITEM
};

class NodeItemFactory
{
    public:
        // Uses a lookup table to map the input string to one of the "mkni" 
        // functions below and then calls it.
        static NodeItemBase* mknifromid(const std::string&amp; id);

    private:
#define ADD_NODE_ITEM(ID) \
    static NodeItemBase* mkni##ID(void) { return new NodeItem##ID(); }
    ADD_NODE_ITEMS
#undef ADD_NODE_ITEM
};

#undef ADD_NODE_ITEMS
</code></pre>

<p>Now for the question:  is using macros to "compact" this code the "right" way
to do this, or is there a more elegant/cleaner approach?  Comments suggesting
an alternative design are also welcome:  I'm still pretty new to
object-oriented programming and don't have a good feel for what's "right" yet.</p>

<p>Thank you very much in advance!</p>
