Möglichkeit zum Mischen von zusammengesetzten Mustern und seltsamerweise wiederkehrenden Schablonenmustern
Ich habe eine zusammengesetzte Musterimplementierung, die für GUI-Komponenten verwendet wird:
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;
}
}
Leider nimmt die Anzahl der geerbten Klassen rapide zu und der doppelte Code (in diesem Beispiel nur die Methode detach ()) bereitet mir Kopfschmerzen.
Gibt es eine Möglichkeit, detach () -Methoden sauber zu implementieren, wobei der Rückgabetyp mit dem Objekt identisch bleibt, für das er aufgerufen wird?
Ich habe über CRTP nachgedacht, kann mir aber keine Möglichkeit vorstellen, den dynamischen Polymorphismus zusammen mit dem Kompilierzeit-Polymorphismus beizubehalten:
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.