在我的模拟中,我有三种不同的物体可以通过三种方式感知:物体可以被看到和/或听到和/或闻到。例如,可以看到,听到和闻到动物。地上的一块肉可以看到和闻到但没有听到,只能看到墙。然后,我有不同的传感器来收集这些信息 - EyeSensor
,EarSensor
,NoseSensor
。
在州之前:简要版gist.github.com link
在我开始实现NoseSensor之前,我在每个对象继承的一个类中都有三个功能 - CanBeSensed
因为虽然类不同,但它们都需要相同的getDistanceMethod()
,如果对象实现了任何CanBeSensed
它需要一个senseMask - 如果可以听到/看到/闻到对象的标志,我不想使用虚拟继承。我牺牲了这个类中的数据成员的气味,声音,EyeInfo
,因为只能看到的对象不需要气味/声音信息。
对象在相应的传感器中注册。
现在我注意到Smell和Sound传感器是相同的,只是在循环内的一行中有所不同 - 一个在getSound()
个对象上调用float float getSmell()
和另一个CanBeSensed*
。当我创建这两个传感器中的一个时,我知道它需要调用什么,但我不知道如何在没有条件的情况下选择该行,并且它位于紧密循环和虚函数内。
所以我决定使用getDistanceMethod()
的基类使用虚拟继承为这3个功能创建一个基类。
但是现在我必须使我的SensorBase类成为模板类,因为这个方法
virtual void sense(std::unordered_map<IdInt, CanBeSensed*>& objectsToSense) = 0;
,这意味着我需要让SensorySubSystem
类(管理范围内的传感器和对象)成为模板。这意味着我的所有子系统,如VisionSubSystem,HearingSubSystem和SmellSubSystem都继承自模板类,它破坏了我的SensorySystem类,该类通过指向SensorySubSystem
类std::vector<SensorySubSystem*> subSystems;
拜托,您能否建议一些解决方案,如何重组这个或如何让编译器在编译时决定(或至少每次调用一次//每个对象创建一次)在Hearing / Smell内部调用什么方法{{1 }}第
答案 0 :(得分:1)
看看你的原创设计我有几点意见:
关于你的新方法:
继承应主要用于表达概念(is-a-relations),而不是用于共享代码。如果要重用算法,请考虑编写算法类或函数(支持组合而不是继承)。
总之,我建议保持原有的课堂设计,如上所述清理一下。您可以将虚拟函数canBeSmelled / canBeHeard / canBeSeen添加到CanBeSensed。
或者,您可以创建一个类层次结构:
但是,你必须处理虚拟继承而没有任何明显的好处 共享计算代码可以进入算法类或函数。