在我的模拟中,我可以通过三种方式感知不同的对象:可以看到和/或听到和/或闻到对象。例如,可以看到,听到和闻到动物。可以看到并闻到一块肉在地面上,但闻不到,只能看到墙。然后,我有收集此信息的不同传感器-EyeSensor
,EarSensor
和NoseSensor
。
之前状态:简短版本gist.github.com link
在开始实现NoseSensor之前,我在一个类中具有所有对象都继承的所有三种功能-CanBeSensed
,因为尽管类不同,但它们都需要相同的getDistanceMethod()
,并且如果对象实现了任何CanBeSensed
功能,则需要SenseMask-标记是否可以听到/看到对象/ smelled,我不想使用虚拟继承。我牺牲了在此类中使用数据成员来获取气味,声音和EyeInfo
,因为只能看到的对象不需要气味/声音信息。
然后将对象注册到相应的传感器中。
现在,我注意到气味传感器和声音传感器是相同的,只是循环中的一行不同-一个在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;
的指针的 vector 来管理所有SensorySubSystems。
请问您是否可以提出一些解决方案,以了解如何重组此结构或如何使编译器在编译时确定(或至少每个调用一次确定//每个对象创建一次确定)在Hearing / Smell Sensor
中调用哪种方法。
最佳答案
看看您的原始设计,我有几点评论:
关于您的新方法:
继承应主要用于表达概念(关系),而不是共享代码。如果要重用算法,请考虑编写算法类或函数(偏重继承而不是继承)。
总而言之,我建议如上所述使您的原始类(class)设计清理干净一点。您可以将虚拟函数canBeSmelled / canBeHeard / canBeSeen添加到CanBeSensed。
或者,您可以创建一个类层次结构:
但是随后您将不得不处理虚拟继承而没有任何明显的好处。
共享的计算代码可以进入算法类或函数。