Подтвердить что ты не робот

Возврат вектора unique_ptr из функции

В настоящее время я просматриваю книгу Head First Object Oriented Analysis and Design и одновременно привык к некоторым функциям С++ 11 (особенно unique_ptr и move semantics). В книге они приводят в качестве примера стратегическую настольную игру. Он имеет доску, плитки и плитки. Код находится в Java, и я пытался переписать его на С++. В Java класс плитки выглядит следующим образом:

public class Tile
{
    private List units;

    public Tile()
    {
        units = new LinkedList();
    }

    protected void addUnit(Unit unit)
    {
        units.add(unit);
    }

    protected List getUnits()
    {
        return units;
    }
}

Я сделал то же самое в С++, сначала используя shared_ptr. Он работал, но очень медленно, по сравнению с моей второй версией, в которой использовались исходные указатели. Затем я попробовал unique_ptr:

class Tile
{

public:
  Tile();
  virtual ~Tile();

  void addUnit()
  {
    mUnits.push_back(std::unique_ptr<Unit>(new Unit());
  }

  std::vector<std::unique_ptr<Unit>> getUnits()
  {
    return mUnits;
  }

private:
  std::vector<std::unique_ptr<Unit>> mUnits;

};

компилятор не любит getUnits. Насколько я понимаю, это происходит из-за того, что конструктор копирования отключен в unique_ptr. Как бы вы вернули список векторов? Спасибо!

4b9b3361

Ответ 1

Значение, возвращаемое в С++, берет копию - если вы этого хотите, вы не можете использовать unique_ptr или должны сделать ручную копию и std::move. Тем не менее, я хочу, чтобы вы только хотели предоставить доступ к Unit (по любой причине...), поэтому просто верните ссылку:

std::vector<std::unique_ptr<Unit>> const& getUnits() const
{
  return mUnits;
}

(const нужен только в том случае, если вы не хотите предоставлять доступ для записи в вектор.)

Теперь возникает еще несколько вопросов: почему ~Tile virtual? Я не вижу необходимости.

Почему вы используете собственный ptr для указания единиц? В исходном коде Java вы получаете ссылку на внешний блок и сохраняете только ссылку - если Tile в коде Java уничтожен, единицы не являются (из того, что я вижу), если они упоминается где-то в другом месте. Чтобы достичь точного результата в С++, вы были правильно используете shared_ptr.

Конечно, вы могли бы просто уточнить, кто является реальным владельцем юнитов и действовать соответственно - если это не Tile, используйте необработанный указатель. См. Также Какой указатель я использую, когда?