派生的类相关函数

Derived class dependent function

本文关键字:函数 派生      更新时间:2023-10-16

我有基类DataProcessor。它是某些坐标系中位置计算器的基类。因此,例如,它可以有像SphericDataProcessorCartesianDataProcessor这样的子体。有一个基类CookedDataCatalogue,它是一些对象位置的容器的基类。因此,每个DataProcessor都应该能够将其数据放入每个CookedDataCatalogue。我可以想象这样的事情:

class CookedDataCatalogue
{
virtual void Transform(DataProcessor* dp) = 0;
virtual void PutData(???) = 0;
}

class CookedDataCatalogue1 : public CookedDataCatalogue
{
void Transform(DataProcessor* dp) override
{
dp->TransformTo(this);
}
}
class CookedDataCatalogue2 : public CookedDataCatalogue
{
...
}
class CookedDataCatalogue3 ...
class DataProcessor
{
virtual void Process() = 0;
virtual void TransformTo(CookedDataCatalogue1* c) = 0;
virtual void TransformTo(CookedDataCatalogue2* c) = 0;
virtual void TransformTo(CookedDataCatalogue3* c) = 0;
}

但我不喜欢。首先,void Transform(DataProcessor*)从基类迁移到所有的孩子身上。其次,如果我将其构建为库,其他用户就不能添加自己的CookedDataUserCatalogue,因为他不能添加另一个void TransformTo(CookedDataUserCatalogue)。第三,我不知道如何编写函数PutData(),因为每个Catalogue都使用自己的数据来包含。它应该被模板化吗?

什么是解决方案?有没有我错过的编程模式?

有两种方法可以做到这一点,还有评论中提到的双重调度模式:

基线

第一种方法是指定一组"基线"坐标。为了先转换到核心集,然后再从核心集转换。

优点:您只需要为任意数量的不同DataProcessors编写一个toBaselinefromBaseline。添加一个新的DataProcessor就像创建它,然后编写与核心集的转换一样简单。

缺点:在大多数情况下,当您进行两次转换时,性能会受到影响。准确性可能会因表示或转换方面的损失而受损。

变压器对象

创建一个将对象从DataProcessor转换为DataProcessor的接口。

为每个支持的转换创建该接口的实例。

拥有一个实用程序类,该类具有要使用的正确转换的源和目标对的映射。在该实用程序类上调用一个方法,以便根据需要执行转换。

优点:无需进行多次转换而造成浪费。

缺点:n^2个Transform对象需要创建,其中n是不同DataProcessor对象的数量。创建新的DataProcessor时,需要为每个添加的DataProcessor编写并添加Transform对象。将在运行时而非编译时检测到缺少的Transform