我有一個合成圖案實現,用於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;
}
}
不幸的是繼承類的數量迅速增加,並且重複的代碼(在給定的例子僅detach()方法)讓我頭疼。
有沒有辦法乾淨地實現detach()方法,保持返回類型與它所調用的對象相同?
我在想CRTP,但我不能想辦法,以保持動態多態性與編譯時多態性沿:
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.
'分離()'方法用於在醜陋的方式: 'CObject的* tree_of_stuff;' - 對象的完整樹 'CSpecificObject * specific_object = tree_of_stuff->子( 「的StringID」) - > detach();' 這裏'Child <>()'方法沿着樹進行搜索並將對象轉換爲指定的模板參數。如果'detach()'返回'void'或'CObject *',則此語法不可用。 –
'duplicate()'方法是一定的錯誤來源,這是我用CRTP擴展當前模式的原因之一。在我看來,依靠複製構造函數是更安全的,承諾每個人都會實現'duplicate()'方法。 –