c – D.R.Y vs“避免宏”

前端之家收集整理的这篇文章主要介绍了c – D.R.Y vs“避免宏”前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在使用 Windows API在C中创建自己的XUL实现.元素由XML解析器构造的事实要求它们具有相同的接口,因此我们不需要为每个元素构造函数编写自定义代码.结果是我的大多数元素看起来像这样:
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

解决方法

我不会在这里使用宏.线索在你的“描述”类中,它有一个额外的成员函数init,其他人没有.因此,您将无法使用宏来定义它,但您需要手动扩展宏并添加额外的行.

对我来说,这是对DRY的更大违反,而不仅仅是写出所有的类定义.几乎没有重复自己,但仅仅针对一个案例,通常最终难以维持一直重复自己. DRY是关于找到好的抽象,而不仅仅是减少样板.

但是,我可以用Element类中的SetAttributes函数替换那些构造函数.这可能会减少每个派生类中实际需要的样板量,因为构造函数是不能从基类继承的东西.但这取决于每个类的构造函数的实现有多相似.

猜你在找的C&C++相关文章