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

В настоящее время я читаю книгу Head First Object Oriented Analysis and Design, а также привыкаю к ​​некоторым функциям C ++ 11 (особенно unique_ptr и семантика перемещения) одновременно. В книге они приводят дизайн настольной игры стратегии в качестве примера. У него есть доска, плитки и юниты на плитках. Код написан на Java, и я пытался переписать его на C ++. В 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;
}
}

Я сделал то же самое в C ++, сначала используя 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. Как бы вы вернули список векторов?
Спасибо!

16

Решение

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

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

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

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

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

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

15

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]