我正在使用
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