【发布时间】:2011-12-09 23:54:26
【问题描述】:
我收集了大约 50 个非常相似的小型结构化类 都源于一个共同的基础。类代表读入的项目 从文件中作为字符串对,其中第一个字符串用于标识 对的类型(应该使用哪个派生类来表示数据)和 第二个是数据本身。还有一个访问者(如访问者模式) 与派生类关联的类和用于生成的工厂类 来自类型标识字符串的适当派生类。
设置如下所示:
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(); }
};
由于这段代码非常重复,占用大量空间,并且由于添加了一个 新的项目类型需要记住在几个地方添加行,我是 使用宏创建派生类并添加:
#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
现在的问题是:使用宏来“压缩”这段代码是“正确”的方式 要做到这一点,还是有更优雅/更清洁的方法?评论建议 也欢迎替代设计:我还是很陌生 面向对象的编程,对什么是“正确的”还没有很好的感觉。
非常感谢您!
【问题讨论】:
-
为什么需要这么多派生类?它们有何不同?
标签: c++