Vyt*_*ius 11 c++ templates design-patterns composite crtp
我有一个复合模式实现,用于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;
}
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,继承类的数量迅速增加,重复的代码(在给定的例子中只有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.
Run Code Online (Sandbox Code Playgroud)
您可以添加一个抽象级别:
class CObjectBase
{
public:
// Other methods...
virtual CObjectBase* detach() = 0;
virtual CObjectBase* duplicate() const = 0;
};
template <typename Child>
class CObject : public CObjectBase
{
public:
// ...
Child* duplicate() const
{
return new Child(*static_cast<Child*>(this));
}
Child* detach()
{
m_pParent->RemoveChild(this);
m_pParent = nullptr;
return static_cast<Child*>(this); // Cast needed here (inherent to CRTP)
}
std::vector<CObjectBase*> children; // Array possible now
// ...
};
class MyObject : public CObject<MyObject>
{
// ...
};
Run Code Online (Sandbox Code Playgroud)
在自然语言中:所有objects(CObjectBase)的接口都有其后代(CObject<Child>)的部分实现,只需继承此部分实现,减少复制代码的数量.
| 归档时间: |
|
| 查看次数: |
1031 次 |
| 最近记录: |