gpt4 book ai didi

预处理器宏代码生成的 C++ 替代方案?

转载 作者:搜寻专家 更新时间:2023-10-31 01:56:41 27 4
gpt4 key购买 nike

我收集了大约 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

现在的问题是:使用宏以“正确”的方式“压缩”这段代码这样做,还是有更优雅/更清洁的方法?评论暗示也欢迎替代设计:我还是很新的面向对象的编程,对什么是“正确的”还没有很好的感觉。

非常感谢您!

最佳答案

您可能想要查看 Andrei Alexandrescu 撰写的“现代 C++ 设计”的拷贝,其中展示了如何使用 C++ 模板系统自动生成大部分此类代码。 Alexandrescu 将两章专门用于访问者模式和自动生成类层次结构,这似乎与您正在寻找的完全一样。我不会尝试复制这个答案中的代码,主要是因为它非常密集,我可能会弄错,而且这本书有更好的解释。 :-)

关于预处理器宏代码生成的 C++ 替代方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6698073/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com