我收集了大约50个小的,非常类似的结构化类, 都来自一个共同的基础。这些类表示在文件中以 作为字符串对读取的项目,其中第一个字符串用于标识对的类型(应使用哪个派生类来表示数据),第二个是数据本身。还有访问者(如访客模式) 与派生类关联的类和用于从类型标识字符串生成 相应派生类的工厂类。C++替代预处理器宏代码生成?
的设置看起来是这样的:
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
现在的问题:使用宏来“紧凑型”这段代码的“正确”的方式 要做到这一点,还是有莫重新优雅/清洁的方法?建议使用 的替代设计也值得欢迎:我对 面向对象编程还很陌生,对于什么是“正确”还没有好的感觉。
非常感谢您提前!
为什么你需要这么多派生类?他们有什么不同? –