实际类的数组

时间:2013-08-12 09:45:08

标签: c++ oop design-patterns

  Ship *ship;

  if (newShipType == 0)
  {
    ship = new SmallShip(gridPosition.x, gridPosition.y,
                         grid->raw);
  }
  else if (newShipType == 1)
  {
    ship = new MediumShip(gridPosition.x, gridPosition.y,
                          grid->raw);
  }
  else // 2
  {
    ship = new BigShip(gridPosition.x, gridPosition.y,
                       grid->raw);
  }

我想要使用以下内容简化的代码:

Ship *ship = new getShipByType[newShipType](gridPosition.x, gridPosition.y, grid->raw);

这样的事情可能吗?

Ship getShipByType[3] = {SmallShip, MediumShip, BigShip};

这给出了:

error: expected primary-expression before ‘,’ token
error: expected primary-expression before ‘,’ token
error: expected primary-expression before ‘}’ token

我并不是真的希望它能够编译,只是寻找一种更简单的方法来做这件事,这只是一次非常长的尝试。

4 个答案:

答案 0 :(得分:5)

您可以委派一个功能来创建不同的船只,它通常被称为工厂模式。数组也不处理多态,你需要使用vector:

#include <memory>

enum ShipType { Small = 0, Medium, Big };

std::unique_ptr<Ship> makeShip(ShipType ship_type, GridPosition position)
{
  switch(ship_type)
  {
    case Small:
      return std::unique_ptr<Ship>(new SmallShip());
    break;
    case Medium:
      return std::unique_ptr<Ship>(new MediumShip());
    case Big
      return std::unique_ptr<Ship>(new BigShip());
    default:
      break;
  } 
  return nullptr;
}

std::vector<std::unique_ptr<Ship>> ships;
ships.push_back(makeShip(Samll));
ships.push_back(makeShip(Medium));
ships.push_back(makeShip(Big));
// now fly your ship!!!

答案 1 :(得分:3)

您可以使用函数指针数组。

向Ship添加静态模板功能将允许它作为工厂。

typedef std::unique_ptr<Ship> (*fnShipCreate)(int,int,void*);
template <class T> static std::unique_ptr<Ship> create(int x, int y, void* raw) { return new T(x, y, raw); }

(注意你没有指定构造函数参数的类型,所以我做了一个合理的猜测......)

这允许如下指定函数指针数组,为每种类型的船创建模板函数的实例:

Ship::fnShipCreate shipCreators[] = { Ship::create<SmallShip>, 
                                      Ship::create<MediumShip>, 
                                      Ship::create<BigShip> };

可以使用(假设原始帖子中的变量名称)来调用它:

std::unique_ptr<Ship> ship = shipCreators[newShipType](gridPosition.x, gridPosition.y, grid->raw);

答案 2 :(得分:2)

我建议为船舶创建实施一个工厂,如下所示:

enum ShipSize { Small, Medium, Big};

class ShipFactory
{
public:
    // consider return std::unique_ptr, shared_ptr or std::auto_ptr
    Ship * createShip(ShipSize size)
    {
        switch (size)
        {
            case Small: return new SmallShip();
            ...
        }
    }
};

要自动化内存管理,您还可以考虑返回std :: unique_ptr(如果您使用新编译器,或者使用shared_ptr,或者如果您使用旧编译器则返回auto_ptr)。

答案 3 :(得分:1)

假设SmallShipMediumShipBigShip是来自Ship的不同派生类,则无法将实例存储在Ship变量中。它必须是一个引用或指针。

正如评论中所提到的,工厂函数绝对是一种可能的解决方案(但是,除了我的书中应该是枚举的类型的硬编码数字之外,它几乎就是你的第一个代码部分) 。