В настоящее время я читаю книгу 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. Как бы вы вернули список векторов?
Спасибо!
Значение, возвращаемое в C ++, влечет за собой копию — если это то, что вы хотите, вы не можете использовать unique_ptr
или нужно сделать ручную копию и std::move
Это. Тем не менее, я полагаю, вы только хотите предоставить доступ к Unit
s (по любой причине …), поэтому просто верните ссылку:
std::vector<std::unique_ptr<Unit>> const& getUnits() const
{
return mUnits;
}
(The const
нужен только если вы не хотите давать права на запись в вектор.)
Теперь возникает несколько вопросов: почему ~Tile
virtual
? Я не вижу необходимости.
Почему вы используете владеющим указывать на единицы измерения? В исходном коде Java вы получаете ссылку на внешний модуль и сохраняете только ссылку — если Tile
в коде Java уничтожены, единицы не (из того, что я вижу), пока они ссылаются где-то еще. Чтобы добиться того же самого в C ++, вы правильно использовали shared_ptr
,
Конечно, вы могли бы просто уточнить кто является реальным владельцем единиц и действовать соответственно — если это не Tile
, используйте необработанный указатель. Смотрите также «Какой тип указателя мне использовать, когда?»
Других решений пока нет …