Как я могу хранить заклинания и предметы, используя реализацию std :: vector?

10

Я следую вместе с книгой из GameInstitute прямо сейчас, и она просит меня:

Разрешить игроку покупать и носить лечебные зелья и зелья огненного шара. Вы можете добавить массив Item (после определения класса элемента) в класс Player для их хранения или использовать std :: vector для их хранения.

Я думаю, что я хотел бы использовать std::vectorреализацию, потому что это, кажется, смущает меня меньше, чем создание класса элемента, но я не уверен, как это сделать. Я слышал от многих людей, что векторы являются отличным способом хранения динамических значений (таких как предметы, оружие и т. Д.), Но я не видел, чтобы они использовались.

Владимир Маренус
источник
3
Вам понадобится класс Item в любом случае. Массив элементов будет Item items [INVENTORY_SIZE]; Std :: vector элементов будет std :: vector <Item> items; Std :: vector - это просто массив, размер которого можно динамически изменять.
API-Beast
1
Для хранения объектов в векторе они должны быть объектами одного типа. Способ сделать это - создать вектор Предметов (где Предмет - это интерфейс для всех предметов, которые можно подобрать) и классы для каждого из типов ваших предметов (зелье исцеления и зелье огненного шара). Пока классы зелий реализуют интерфейс Item, вы можете хранить их в векторе (хотя по мере усложнения вещей вы можете захотеть добавить больше интерфейсов для таких вещей, как расходуемые предметы, составные предметы или просто сами зелья. Но для простоты просто сделайте один класс на предмет и интерфейс Предмета)
Бенджамин Дэнджер Джонсон

Ответы:

13

std::vectorэто прекрасный способ хранить «динамические» (как вы их называете) вещи, такие как предметы, но реальное преимущество вектора заключается не в том, что вещи, которые вы храните, могут измениться, а в том, что количество элементов в векторе может меняться без минимальных усилия с вашей стороны. Чтобы проиллюстрировать, если бы вы хранили свои Itemобъекты в виде массива, вы должны были бы зафиксировать размер массива во время компиляции ( Item items[SIZE];), что означает, что у вас есть фиксированный верхний предел для элементов (среди других проблем, которые не ' Это относится к этой конкретной теме, поэтому я пропущу их).

Вы также можете динамически размещать массив во время выполнения ( Item * items = new Item[SIZE];), что позволит вам позже изменить размер массива, выделив новое хранилище, скопировав элементы и удалив старое хранилище. Это, однако, гораздо больше работы для вас.

К счастью, это то, что std::vectorвам нужно - это, по сути, реализация массива динамического размера, которая управляет памятью для увеличения массива за пределы его текущей емкости. Это определенно вариант, который я бы посоветовал вам продолжить, но учтите, что вы все равно захотите создать Itemкласс.

Это очень легко использовать:

// Create an item list and two item objects to add to it.
std::vector<Item> items;
Item fireballPotion("Potion of Fireball");
Item healingPotion("Potion of Healing");

// Add the items:
items.push_back(fireballPotion);
items.push_back(healingPotion);

// operator[] is supported for accessing items.
// This will print "Potion of Fireball" for example:
std::cout << items[0].GetName();

Документацию по MSDN для vectorкласса , вероятно, стоит прочитать, и если вы не знакомы с шаблонами, которые vectorиспользуются для хранения «чего-либо», вам также следует освежить в них основы. Что также подводит меня к последнему пункту: хотя вектор выглядит так, как будто он может хранить что угодно, у него есть ограничения на то, что в нем разрешено, и это иногда бросает новичков. В частности, тип, который вы храните в векторе, должен быть копируемым, потому что вектору необходимо будет, например, сделать копию объектов при изменении размера его внутреннего хранилища. Правило трех в C ++ - это то, что нужно иметь в виду.


источник
Спасибо, это было ясно и кратко. Я сейчас перечитываю документацию. Когда у меня будет 15 представителей, я обязательно вернусь и проголосую за вас!
Владимир Маренус