运行时转换对象,具体取决于实例变量(C ++)

时间:2015-10-01 17:53:55

标签: c++ design-patterns

我正在尝试表示对象的二维地图。所以我有一个二维的“MapItems”数组:

MapItem* world_map[10][10];

在我的特定情况下,这些MapItem将用于表示无人机,静态对象(如树木或任何不移动的障碍物)或空位置(这些对象将是MapItem的子类):

class Drone : public MapItem {
  int droneId;
  ...
}

class StaticObject : public MapItem {
  ...
}

class EmptyPosition : public MapItem {
  int amount_of_time_unoccupied;
  ...
}

在MapItem类上有一个实例变量是一个好主意,它告诉它是什么特定类型的项目,然后基于它将其转换为正确的类型?例如:

enum ItemType = {DRONE, STATIC_OBSTRUCTION, EMPTY};
class MapItem {
  ItemType type;
  ...
}

然后当我想知道地图中某个位置的位置时,我会这样做:

MapItem *item = world_map[3][3];
if (item->type == DRONE) {
  Drone *drone = dynamic_cast<Drone*>(item);
  // Now do drone specific things with drone
  ...
} else if (item->type == STATIC_OBSTRUCTION) {
  StaticObject *object = dynamic_case<StaticObject*>(item);
  // Static object specific stuff
  ...
} else {
  ...
}

我实际上没有尝试过这个,但我认为这是可能的。我真正要问的是这是一个很好的设计模式吗?或者有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

A&#34;打开类型&#34;经常表示设计问题。

您通常要做的是为您关心的行为定义和实现一些虚拟功能。例如,您可能会关心飞入其中一个空间。如果是这样,您可能有一个函数来查看它是否允许输入。如果无人机试图飞向露天,那将返回true,如果它试图飞到树上,则返回假。

顺便说一句,如果您将要派生对象,则需要将数组定义为容器指针,而不是基类的实际对象。否则,当您尝试将派生对象放入数组中时,它会得到&#34;切片&#34;成为基类的对象。