ho un'implementazione composite, usato per componenti GUI:Possibilità di mescolare composite e mascherina modello curiosamente ricorrenti
class CObject {
private:
CObject * m_pParent;
CObjectContainer * m_pChildren;
void private_foo() {
this->foo();
//Calls private_foo for each child in container.
m_pChildren->foo();
}
public:
virtual void foo() {
//empty for base class
}
virtual CObject * duplicate() {
//Do duplication code
return new CObject(*this);
}
virtual CObject * detach() {
//Remove this object (along with it's children)
//from current tree.
m_pParent->RemoveChild(this);
m_pParent = nullptr;
return this;
}
}
class CSpecificObject : public CObject {
public:
virtual void foo() {
//Specific code for this class
}
virtual CSpecificObject * duplicate() {
//Overload, but the code only calls diferent constructor
return new CSpecificObject(*this);
}
virtual CSpecificObject * detach() {
//Note the code is identical.
m_pParent->RemoveChild(this);
m_pParent = nullptr;
return this;
}
}
Purtroppo il numero di classi ereditate aumenta rapidamente e il codice duplicato (in data esempio, solo il il metodo detach()) mi sta facendo venire il mal di testa.
C'è un modo per implementare in modo pulito i metodi detach(), mantenendo il tipo restituito uguale all'oggetto, sul quale viene chiamato?
Stavo pensando di CRTP, ma non riesco a pensare a un modo per mantenere il polimorfismo dinamico con compilazione tempo polimorfismo:
template <Child>
class CObject {
private:
...
Child * detach() {
m_pParent->RemoveChild(this);
m_pParent = nullptr;
return static_cast<Child*>(this);
}
...
}
//Array of CObject* pointers is no longer possible.
'detach()' metodo viene utilizzato in maniera brutta: 'CObject * tree_of_stuff;' - Un albero pieno di oggetti 'CSpecificObject * specific_object = tree_of_stuff-> Bambino ("stringID") -> detach(); ' Qui il metodo' Child <>() 'esegue una ricerca lungo l'albero e lo proietta sul parametro template specificato. Questa sintassi non è disponibile se 'detach()' restituisce 'void' o' CObject * '. –
Il metodo 'duplicate()' è una certa fonte di errori, questo è uno dei motivi per cui sto estendendo il modello corrente con CRTP. A mio avviso, affidarsi a copy constructor è più sicuro che, con la promessa che tutti implementeranno il metodo 'duplicate()'. –