gpt4 book ai didi

c++ - D.R.Y 与 "avoid macros"

转载 作者:可可西里 更新时间:2023-11-01 18:40:08 28 4
gpt4 key购买 nike

我正在使用 Windows API 在 C++ 中创建自己的 XUL 实现。元素由 XML 解析器构造的事实要求它们具有相同的接口(interface),因此我们不需要为每个元素构造器编写自定义代码。结果是我的大部分元素看起来像这样:

class Button : public Element
{
public:
static const char * Type() { return "button"; }

private:
friend class Element;
Button(Element * inParent, const AttributesMapping & inAttributesMapping);
};


class Label : public Element
{
public:
static const char * Type() { return "label"; }

private:
friend class Element;
Label(Element * inParent, const AttributesMapping & inAttributesMapping);
};


class Description : public Element
{
public:
static const char * Type() { return "description"; }

virtual bool init();

private:
friend class Element;
Description(Element * inParent, const AttributesMapping & inAttributesMapping);
};

所以这里有很多代码重复。我想知道用这样的宏调用替换它们是否是个好主意:

#define DECLARE_ELEMENT(ElementType, XULName)           \
class ElementType : public Element \
{ \
public: \
static const char * Type() { return XULName; } \
\
private: \
friend class Element; \
ElementType( \
Element * inParent, \
const AttributesMapping & inAttributesMapping); \
}; \


DECLARE_ELEMENT(Window, "window")
DECLARE_ELEMENT(Button, "button")
DECLARE_ELEMENT(Label, "label")

我还没有完全弄清楚这个概念,所以这里缺少一些东西,比如类定义,以及(可能)为每个元素添加方法的能力。

但我想知道您对在这种情况下使用宏的看法。欢迎分享您的想法。

编辑

我现在正在使用一个小的 ruby​​ 脚本,它从一组模板生成源文件和头文件。我增强了脚本,以便文件也自动标记为在 SVN 上添加,并且修改了 Visual Studio 项目文件以包含这些文件。这为我节省了大量的体力劳动。我对这个解决方案很满意。仅供引用,这是模板现在的样子:

#ifndef {{ELEMENT_NAME_UPPER}}_H_INCLUDED
#define {{ELEMENT_NAME_UPPER}}_H_INCLUDED


#include "XULWin/Element.h"


namespace XULWin
{

class {{ELEMENT_NAME}} : public Element
{
public:
static ElementPtr Create(Element * inParent, const AttributesMapping & inAttr)
{ return Element::Create<{{ELEMENT_NAME}}>(inParent, inAttr); }

static const char * Type() { return "{{ELEMENT_TYPE}}"; }

virtual bool init();

private:
friend class Element;
{{ELEMENT_NAME}}(Element * inParent, const AttributesMapping & inAttributesMapping);
};

} // namespace XULWin


#endif // {{ELEMENT_NAME_UPPER}}_H_INCLUDED

CPP 文件:

#include "XULWin/{{ELEMENT_NAME}}.h"
#include "XULWin/{{ELEMENT_NAME}}Impl.h"
#include "XULWin/AttributeController.h"
#include "XULWin/Decorator.h"


namespace XULWin
{

{{ELEMENT_NAME}}::{{ELEMENT_NAME}}(Element * inParent, const AttributesMapping & inAttributesMapping) :
Element({{ELEMENT_NAME}}::Type(),
inParent,
new {{ELEMENT_NAME}}Impl(inParent->impl(), inAttributesMapping))
{
}


bool {{ELEMENT_NAME}}::init()
{
return Element::init();
}

} // namespace XULWin

最佳答案

如果您使用模板解决方案,您可以避免宏避免重复自己:

template <const char *XULName>
class ElementType : public Element
{
public:
static const char * Type() { return XULName; }

private:
friend class Element;
ElementType(
Element * inParent,
const AttributesMapping & inAttributesMapping);
};

char windowStr[]="window";
char buttonStr[]="button";
char labelStr[]="label";

typedef ElementType<windowStr> Window;
typedef ElementType<buttonStr> Button;
typedef ElementType<labelStr> Label;

经验法则:模板几乎可以用于 C 中宏所必需的所有内容。

实现注意事项:字符串文字不能直接用作模板参数,因为它们具有内部链接——这就是为什么您需要 windowStr 等。在实践中,您可能希望将声明放在H文件中的windowStrbuttonStrlabelStr以及CPP文件中这些字符串的定义。

关于c++ - D.R.Y 与 "avoid macros",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1554910/

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