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

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

次のような船の作成用のファクトリを実装することを提案します。

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、インスタンスを変数に格納することはできません。参照またはポインタでなければなりません。MediumShipBigShipShipShip

コメントで述べたように、ファクトリ関数は間違いなく可能な解決策です (ただし、私の本の列挙型である必要がある型のハードコードされた数値は別として、最初のコード セクションとほぼ同じです)。

于 2013-08-12T09:52:07.163 に答える