Posibilidad de mezclar patrón compuesto y patrón de plantilla curiosamente recurrente
Tengo una implementación de patrón compuesto, utilizada para componentes GUI:
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;
}
}
Desafortunadamente, el número de clases heredadas aumenta rápidamente y el código duplicado (en el ejemplo dado, solo el método detach ()) me está dando un dolor de cabeza.
¿Hay una manera de implementar limpiamente los métodos detach (), manteniendo el tipo de retorno igual que el objeto, en el que se llama?
Estaba pensando en CRTP, pero no puedo pensar en una manera de mantener el polimorfismo dinámico junto con el polimorfismo de tiempo de compilación:
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.