Mam kompozytowego realizację wzór, używany komponentów GUI:Możliwość mieszać kompozytowego wzór i ciekawie cykliczne szablon wzór
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;
}
}
Niestety liczba dziedziczonych klas wzrasta gwałtownie i kod duplikat (w podanym przykładzie tylko metoda detach()) sprawia mi ból głowy.
Czy istnieje sposób czyszczenia implementacji metod detach(), zachowując typ zwrotu taki sam jak obiekt, na który jest wywoływany?
Myślałam o CRTP, ale nie mogę myśleć o sposób, aby utrzymać polimorfizm dynamiczny wraz z kompilacji polimorfizmu:
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.
'odłączy()' metoda jest stosowana w brzydki sposób: 'CObject * tree_of_stuff;' - Pełne drzewo obiektów 'CSpecificObject * specific_object = tree_of_stuff-> Dziecko ("stringID") -> detach(); ' W tym przypadku metoda' Child <>() 'przeszukuje drzewo i rzuca obiekt na określony parametr szablonu. Ta składnia jest niedostępna, jeśli 'detach()' zwraca 'void' lub' CObject * '. –
'duplicate()' metoda jest pewnym źródłem błędów, to jest jeden z powodów, dla których przedłużam bieżący wzór za pomocą CRTP. Moim zdaniem poleganie na konstruktorze kopii jest bezpieczniejsze, jeśli obiecuję, że wszyscy wdrożą metodę 'duplicate()'. –