我收集了大約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
現在的問題:使用宏來「緊湊型」這段代碼的「正確」的方式 要做到這一點,還是有莫重新優雅/清潔的方法?建議使用 的替代設計也值得歡迎:我對 面向對象編程還很陌生,對於什麼是「正確」還沒有好的感覺。
非常感謝您提前!
爲什麼你需要這麼多派生類?他們有什麼不同? –