可以混合复合模式和奇怪的重复模板模式
Possibility to mix composite pattern and curiously recurring template pattern
我有一个复合模式实现,用于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.
您可以添加一个抽象级别:
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>
{
// ...
};
在自然语言中:所有对象的接口(CObjectBase
)对其后代(CObject<Child>
)都有一个部分实现,它只需要继承这个部分实现,减少复制代码的数量。
我在考虑 CRTP,但我想不出一种方法来保持动态多态性以及编译时多态性
您可以通过使用 CRTP 样式基类为某些接口提供默认虚拟实现来混合它们。
因此,您可以聚合 CRTP 基本实现(可能配置了其他"策略"模板参数),并且仍然能够覆盖继承类中的特定行为。
Microsoft的ATL库经常使用它。我还在我的 STTCL 状态机库中使用了这种技术。
仅从代码片段来看,尚不清楚为什么需要detach()
返回指向已交付类型的指针。
若要利用返回已传递类型的detach()
,无论如何都需要使用对已传递类型的引用来调用它。喜欢这个:
CSpecificObject* specific_object = new SpecificObject();
// ...
specific_object->detach()->method_declared_in_specific_object();
但这可以用即使分离无效也能工作的等效项替换:
specific_object->detach();
specific_object->method_declared_in_specific_object();
如果引用了基类型,则无法利用detach()
返回类型:
CObject* specific_object = new SpecificObject();
//...
// !!! Won't compile:
specific_object->detach()->method_declared_in_specific_object();
出于这个原因,目前尚不清楚您尝试实施的方法的优势是什么。
一面不是duplicate()
方法很臭。当传递的类不覆盖它,但使用父类的默认实现时,它会中断。这可能表明高级设计有问题。
相关文章:
- OpenCV 混合模式实现:为什么看似等效的操作会产生不同的结果?
- 混合模式程序集是针对版本 'v2.0.50727' 构建的 ...本机C++/Visual C++/C# 项目错误
- Visual Studio混合模式调试是否可以附加到Jupyter笔记本以同时调试C++和Python
- 如何链接到C++/Cli混合模式dll中的本机类
- 可以混合复合模式和奇怪的重复模板模式
- 通用设计与奇怪的重复模板模式混合在一起.C++
- 调试混合模式应用程序(C# 和非托管 C++)时"The breakpoint will not currently be hit"错误
- 混合模式程序集(C++/CLI项目)在.NET Core上工作吗
- 将命令模式,工厂模式和模板混合在一起..
- 错误:"混合的隐式和静态模式规则"在我的生成文件中
- 具有混合依赖项的生成文件模式规则
- 如何处理混合模式项目中的打印
- c++ (Direct2D) 中的混合模式
- C++中的两种不同的mixin模式.(混合蛋白?CRTP?)
- 链接到混合模式dll中的presentationcore.dll
- 通过混合模式c++ /CLI DLL从ETL工具中使用托管c# DLL -可能
- 内存管理在c++混合模式下的应用
- 如何将使用boost::asio的本地c++静态库导入CLI/ c++混合模式应用程序?
- 卸载混合模式组件
- 如何在文本模式下安全地混合 std::ifstream 的 tellg、seekg 和 read(*,n) 方法