Jak mogę przechowywać pisownię i przedmioty za pomocą implementacji std :: vector?

10

W tej chwili śledzę książkę GameInstitute, która wymaga ode mnie:

Pozwól graczowi kupować i nosić mikstury lecznicze oraz mikstury ognistej kuli. Możesz dodać tablicę przedmiotów (po zdefiniowaniu klasy przedmiotu) do klasy odtwarzacza w celu ich przechowywania lub użyć std :: vector do ich przechowywania.

std::vectorWydaje mi się, że chciałbym skorzystać z implementacji, ponieważ wydaje mi się to mniej mylić niż tworzenie klasy przedmiotów, ale nie jestem pewien, jak to zrobić. Słyszałem od wielu ludzi, że wektory są świetnymi sposobami do przechowywania wartości dynamicznych (takich jak przedmioty, broń itp.), Ale nie widziałem, aby były używane.

Vladimir Marenus
źródło
3
Będziesz potrzebował klasy przedmiotu w jakikolwiek sposób. Tablica elementów to pozycje przedmiotów [INVENTORY_SIZE]; Std :: vector przedmiotów byłoby std :: vector <Item> przedmioty; Std :: vector to tylko tablica, której rozmiar można dynamicznie zmieniać.
API-Beast,
1
Aby przechowywać obiekty w wektorze, muszą to być obiekty tego samego typu. Można to zrobić poprzez utworzenie wektora przedmiotu (gdzie przedmiot jest interfejsem dla wszystkich przedmiotów, które można podnieść) i klas dla każdego z twoich typów przedmiotów (mikstura lecznicza i mikstura ognista). Tak długo, jak klasy mikstur implementują interfejs przedmiotów, możesz przechowywać je w wektorze (chociaż w miarę komplikowania rzeczy możesz chcieć dodać więcej interfejsów dla rzeczy takich jak przedmioty konsumpcyjne, przedmioty do układania w stosy lub same mikstury. Ale dla uproszczenia po prostu zrób jedna klasa na przedmiot i interfejs przedmiotów)
Benjamin Danger Johnson

Odpowiedzi:

13

std::vectorto świetny sposób na przechowywanie „dynamicznych” (jak je nazywasz) rzeczy, takich jak przedmioty, ale prawdziwą zaletą wektora nie jest to, że rzeczy, które przechowujesz, mogą się zmieniać, ale że liczba elementów w wektorze może się zmieniać bez minimalnego wysiłek z twojej strony. Aby to zilustrować, gdybyś miał przechowywać swoje Itemobiekty jako tablicę, musiałbyś ustalić rozmiar tablicy w czasie kompilacji ( Item items[SIZE];), co oznacza, że ​​masz ustalony górny limit na przedmioty (wśród innych problemów, które nie są jako odpowiednie dla tego konkretnego tematu, więc pominę je).

Możesz także dynamicznie przydzielić tablicę w runtime ( Item * items = new Item[SIZE];), co pozwoli później zmienić rozmiar tablicy, przydzielając nową pamięć, kopiując elementy i usuwając starą pamięć. Jest to jednak o wiele więcej pracy do wykonania.

Na szczęście to właśnie std::vectorrobi dla Ciebie - jest to zasadniczo implementacja macierzy o dynamicznym rozmiarze i obsługuje zarządzanie pamięcią w celu powiększenia macierzy poza jej obecną pojemność. Zdecydowanie jest to opcja, którą sugeruję na razie - ale pamiętaj, że nadal będziesz chciał stworzyć Itemklasę.

Jest bardzo łatwy w użyciu:

// 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();

Dokumentacja MSDN dla tej vectorklasy jest prawdopodobnie warta przeczytania, a jeśli nie znasz szablonów - co vectorpozwala jej na przechowywanie „czegokolwiek” - powinieneś odświeżyć również podstawy. Co prowadzi mnie również do ostatniego punktu: chociaż wygląda na to, że wektor może przechowywać wszystko, ma ograniczenia co do tego, co jest w nim dozwolone, i czasami rzucają początkujących. W szczególności typ przechowywany w wektorze musi być możliwy do skopiowania, ponieważ wektor będzie musiał np. Wykonać kopię obiektów podczas zmiany rozmiaru pamięci wewnętrznej. Należy pamiętać o regule trzech C ++ .


źródło
Dziękuję, to było jasne i zwięzłe. Czytam teraz dokumentację. Kiedy mam 15 przedstawicieli, upewnię się, że wrócę i zagłosuję!
Vladimir Marenus,