Sto creando la mia implementazione di XUL in C++ utilizzando l'API di Windows. Il fatto che gli elementi siano costruiti dal parser XML richiede che abbiano interfacce identiche, quindi non è necessario scrivere codice personalizzato per ogni costruttore di elementi. Il risultato è che la maggior parte dei miei elementi assomiglia a questo:D.R.Y vs "avoid macros"
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);
};
Quindi c'è molta duplicazione di codice qui. Mi chiedo se sarebbe una buona idea per sostituirli con le chiamate di macro come questo:
#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")
non ho completamente elaborati il concetto ancora, quindi alcune cose sono mancanti qui, come le definizioni di classe, e (forse) la possibilità di aggiungere metodi per elemento.
Ma mi piacerebbe sapere la tua opinione sull'utilizzo di macro in questa situazione. Sentiti libero di condividere i tuoi pensieri.
EDIT
ora sto usando un piccolo script Ruby che genera i file di origine e colpo di testa da una serie di modelli. Ho migliorato gli script in modo che anche i file vengano automaticamente contrassegnati per l'aggiunta su SVN e il file di progetto di Visual Studio viene modificato per includere i file. Questo mi fa risparmiare un sacco di lavoro manuale. Sono abbastanza contento di questa soluzione. FYI questo è ciò che i modelli sembrano ora: documento
#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
Supporto SOSTANZA. rendere le cose più pulite. – mauris
Uso principalmente le macro per evitare la ripetizione * di simboli * in una o due righe. Un muro '# define' come il tuo può spesso essere risolto con una funzione/template helper e - a volte - una macro di dichiarazione semplificata. MartinB ha dimostrato una buona soluzione per il tuo caso, senza nemmeno bisogno di una macro. – peterchen
Allora, perché non stai semplicemente facendo la versione del modello? – GManNickG