0

我正在开发人员疏散模拟器。启动时,它将从 XML 文件中加载树状的建筑结构数据(地板/房间/墙壁等),加载人员的初始配置,读取用户定义的移动模型参数并开始模拟。例如,对于每个模型步骤中的每个人,我需要找到他附近的所有几何对象,并选择离建筑物最近的路径 - 尽可能快。

所以,我需要加载一个明确的 OOP 方式来表示人们将移动的建筑物。我坚持这个(只是例子):

class Aperture
{
   ...
public:
    virtual QRectF extent() = 0;
    virtual QString description() const = 0;
    // other common for all apertures methods

private:
   int m_srcRoomID;
   int m_dstRoomID;
   // other generic aperture properties
};

class Window: Aperture
{
    ...
public:
    virtual void extent() override;
    virtual QString description() override;
    // other overrides

private:
    EGlassType m_glassType;
    bool m_bOpenable;
    // other window-specific properties
};

// and other descendants: Door, CompositeDoor and so on

问题:我想将所有构建孔径存储在一个集合中作为抽象基础的指针Aperture,并且只使用基础虚拟函数而不对派生孔径进行任何转换。
但是:在疏散期间,各种 Aperture 属性可能会发生变化,所以我需要以类型相关的方式修改它们。我不能使这个功能通用并将其放在基类中:窗户没有关闭,防火门不怕火 - 但其他人会,等等。可能有一种方法(例如设计模式)来动态存储/添加/删除这些属性?或者完全避免子类化,因为建筑项目的完整层次结构非常复杂和笨重。

4

2 回答 2

0

您可以添加一个虚函数来设置基类 Aperture 中的属性,例如

虚空更新(向量)= 0;或虚拟 void update(...) = 0;

于 2013-01-23T10:40:16.557 回答
0

好吧,决定关门的实体需要知道它可以关闭,它甚至应该考虑改变那个状态。以下是一些选项:

  • 让对象在一个通用的虚拟方法(类似 , 或类似的东西)中Aperture::update自行决定Aperture::interactWithFireAperture::iteractWithPerson
  • 使用访问者模式,即创建virtual Aperture::visit将在访问者上调用适当重载的方法。这允许您仅为有意义的对象组合定义交互方法。
  • 使用“接口”,比如IClosable在任何可以关闭的地方,比如Door在适当的地方。IClosable * closable = dynamic_cast<IClosable *>(apperture); if(closable) { /* consider whether it should be closed */ }实际上,您可能也会将此类接口与访问者模式一起使用,以减少必要的重载次数。

如果其中任何一种或任何组合对您有用,那么面向对象的方法是可行的。

于 2013-01-23T10:40:28.077 回答