我正在尝试解决C ++中涉及并行继承的问题。我发现的最近的问题是Parallel inheritance trees, where classes from one tree have containers of classes from another,但它并没有完全回答我的问题。
我有一个由三个类组成的模型:Model,Trainer,InstanceProcessor(IP),它们分别包含模型数据,训练函数和模型处理代码。现在我有大约10个不同版本的这个模型,有很多代码重叠但有些差异,创建了某种形式的并行继承:
Model - ModelA, ModelB, ModelC, ...
Trainer - TrainerA, TrainerB, TrainerC
IP - IPA, IPB, IPC
在代码的主体中,我使用Model *指针根据解析的参数访问特定的模型。
Model和Trainer都需要多个短暂的IP实例,Model还需要一个Trainer的永久实例。
我当前的实现使用三个基类和一些虚函数,然后模拟从这些基类继承的特定类。这需要我使用大量的铸件(例如,从model.h中的Trainer *培训师到TrainerA,以满足特定需求)。
我怀疑有一种更优雅的方式来实现这个(使用模板/接口?),并且想知道是否有人能指出我正确的方向?谢谢!
编辑:为了澄清以下答案中的一点,其中一个复杂因素在于我想要的事实。 Trainer类具有函数basic_train():
Trainer::basicTraining() {
...
IP* ip = new IP(some args);
ip->doStuff();
...
}
现在根据所使用的培训师类型创建适当的IP。该函数的其余部分不会从TrainerA更改为TrainerB实例。
答案 0 :(得分:2)
当两个单独的层次结构的成员紧密耦合时,继承不会给你带来太大的影响。应该可以使用混合匹配策略的继承promises(即ModelA
使用TrainerB
和IPC
),而实际上这不起作用。
A
,B
,C
组)将同一组的成员视为高度专业化。因此,虽然继承可能对继承层次结构的各个部分不利,但它可能对您的主程序有利。
这将引导您使用abstract factory模式的可行解决方案。主应用程序有一个“工厂工厂”,可以根据传入的内容为其提供FactoryA
,FactoryB
或FactoryC
。每个FactoryX
生成{{1} }},ModelX
和TrainerX
个对象,将它们作为公共超类(即IPX
,Model
和Trainer
)呈现给您的主程序。< / p>
然而,在工厂的胆量中,实施对象是在了解“对应物”的确切类型的基础上创建的。例如,当IP
配置了ModelA
时,它不会使用Trainer
类型的对象 - 它会获得Trainer
。由于TrainerA
知道它创建的对象之间的依赖关系,因此提供正确类型的对象没有问题。与此同时,主程序并不知道这种专业化,而且(FactoryA
,ModelA
和TrainerA
)部分对概括性几乎一无所知。
答案 1 :(得分:1)
基本上播放很糟糕,因为它很脆弱(你应该忘记在你应该的时候更新代码)。相反,你应该利用多态性。我想你可能想看一下visitor pattern,这可能与你最初使用接口的想法相符。
答案 2 :(得分:0)
用更抽象的术语来表示:你有一组已经针对继承而修复的类,并且你希望根据用例使每个类的行为都不同。
在这种情况下,大多数情况下依赖注入或策略会有所帮助:您可以为每个方法调用执行此操作,或者您可以在对象是创建。
在第一种情况下,你传入 - 作为参数 - 改变方法行为的东西(见下文)。
在第二种情况下,您将该参数传递给构造函数,并且对象必须存储该“某事”。
'something'可以像一组固定的值(例如enum)一样简单,也可以是callback / functor / lambda或object。选择任何舒适的东西,重点是它可以改变对象的行为,即使它们都是同一个类。