问题描述
我有一个约50个小的,非常类似的结构化类的集合,
都来自一个共同的基础。类表示在
中从文件中读取的作为字符串对的项,其中第一个字符串用于标识对的
类型(该派生类应用于表示数据)和
第二个是数据本身。还有一个访问者(如在访问者模式中)
类与派生类相关联,以及一个工厂类,用于从类型标识字符串生成适当的派生类
。
I have a collection of about 50 small, very similary structured classes thatall derive from a common base. The classes represent items that are read infrom a file as pairs of strings, where the first string is used to identify thetype of the pair (which derived class should be used to represent the data) andthe 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 generatingthe appropriate derived class from the type identification string.
这个设置看起来像这样:
The setup looks something like this:
class NodeItemVisitor; // Forward declaration.
class NodeItemBase
{
public:
std::string get_val() const { return val; }
virtual std::string idstr() const = 0;
virtual void accept(NodeItemVisitor& v) = 0;
private:
std::string val;
};
// Forward 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 { return "A"; }
virtual void accept(NodeItemVisitor& v) { v.visit(*this); return; }
};
...
class NodeItemZ : public NodeItemBase
{
public:
virtual std::string idstr() const { return "Z"; }
virtual void accept(NodeItemVisitor& 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& id);
private:
static NodeItemBase* mkniA(void) { return new NodeItemA(); }
...
static NodeItemBase* mkniZ(void) { return new NodeItemZ(); }
};
由于这个代码非常重复,占用了很多空间, b新项目类型将需要记住在几个地方添加行,我是
使用宏来创建派生类并添加:
Since this code is very repetitive, takes up a lot of space, and since adding anew item type would require remembering to add lines in several places, I amusing macros to create the derived classes and to add :
#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& 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 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& 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
现在的问题是:紧凑这个代码正确的方式
做到这一点,还是有更优雅/更清洁的方法?评论建议
一个替代设计也是受欢迎的:我仍然是新的
面向对象编程,并没有什么是正确的的好感觉。
Now for the question: is using macros to "compact" this code the "right" wayto do this, or is there a more elegant/cleaner approach? Comments suggestingan alternative design are also welcome: I'm still pretty new toobject-oriented programming and don't have a good feel for what's "right" yet.
非常感谢你!
推荐答案
您可能想要查看现代C ++设计,由Andrei Alexandrescu介绍,它展示了如何使用C ++模板系统自动生成大部分代码。 Alexandrescu为访问者模式创建了两个章节,并自动生成类层次结构,这看起来就像你正在寻找的一样。我不会尝试在这个答案复制代码,主要是因为它是非常密集,我可能会错了,这本书有一个更好的解释。 : - )
You may want to check out a copy of "Modern C++ Design," by Andrei Alexandrescu, which shows how to automatically generate most of this code using the C++ template system. Alexandrescu dedicates two chapters to the visitor pattern and automatically generating class hierarchies, which seems exactly like what you're looking for. I won't try to replicate the code in this answer, primarily because it's really dense, I'd probably get it wrong, and the book has a much better explanation. :-)
这篇关于C ++替代预处理器宏代码生成?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!