3
  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

4 回答 4

5

你可以委托一个函数来创建不同的船,这通常被称为工厂模式。数组也不处理多态性,你需要使用向量来代替:

#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!!!
于 2013-08-12T10:12:36.767 回答
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);
于 2013-08-12T10:41:19.667 回答
2

我建议为 Ship 创建实现一个工厂,如下所示:

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)。

于 2013-08-12T09:51:12.630 回答
1

假设SmallShip和是不同的派生类MediumShip,则不能将实例存储在变量中。它必须是引用或指针。BigShipShipShip

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

于 2013-08-12T09:52:07.163 回答