Y
Sipps schrieb:
eine frage habe ich doch noch, wenn ich das in Vektoren speichere, wie kann ich dann die Ausgabe sortieren?
Inkludiere den Header "algorithm" der STL und benutze einen der gegebenen Sortieralgorithmen.
http://www.cplusplus.com/reference/algorithm/
Gegebenenfalls musst du dir einen eigenen Funktor schreiben um
deine Items zu vergleichen.
http://stackoverflow.com/questions/356950/c-functors-and-their-uses
http://www.cprogramming.com/tutorial/functors-function-objects-in-c++.html
Wenn du dich beim Design des Inventarsystems dafür entscheidest die Vererbungsmethode zu benutzen, sprich eine Basisklasse von der alle Items erben, dann beachte beim auslegen des Designs, dass du nicht auf das Diamantproblem stößt.
https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem
Um alle Items in einem Container speichern zu können, benötigst du eine generische Basisklasse, z.B. ItemInterface, von der alle Items erben. Dann erstellst du eine Instanz des Items und speicherst einen Zeiger vom Typ ItemInterface* in deinem Container. Das hat den Nachteil, dass wenn du dich zum Beispiel für einen std::vector entscheidest, zwar die Zeiger im Speicher kontinuierlich gespeichert sind, die Objekte selbst aber irgendwo im Speicher herumfliegen, was das Iterieren des Containers verlangsamt. ( Das sollte bei einem kleinem Spiel allerdings keinen großen Einfluss haben. ) Wie du schnell merken wirst, kannst du beim Zugreifen auf Items aus dem Vektor nur die Funktionen der Basisklasse aufrufen. Um dies zu umgehen kannst du entweder (pure) virtuelle Methoden in der Basisklasse definieren und von den erbenden Klassen überschreiben lassen oder du castest(?de) den Basisklassenzeiger zu einem Zeiger auf die richtige erbende Klasse ( Item* ).
http://www.cplusplus.com/doc/tutorial/typecasting/
Bitte vergiss dabei nicht den Destruktor der Basisklasse als virtuell zu deklarieren.
( https://www.c-plusplus.net/forum/96988-full )
Anschließend kann ich noch dazu raten intelligente Zeiger ( z.B. std::unique_ptr<ItemInteface> ) anstelle von Rohzeigern ( ItemInterface* ) zu verwenden. Diese löschen das Objekt automatisch sobald es aus dem Anwendungsbereich fällt. ( Verhindert Speicherlecks )
http://www.cplusplus.com/reference/memory/
https://de.wikibooks.org/wiki/C%2B%2B-Programmierung/_Speicherverwaltung/_Smart_Pointer
Die Deklaration des Containers würden dann zum Beispiel so aussehen:
std::vector<std::unique_ptr<ItemInterface>> items_;
Items hinzufügen kannst du dann auf die zum Beispiel auf folgende Art und Weise:
#include <iostream>
#include <memory>
#include <vector>
class ItemInterface
{
public:
virtual ~ItemInterface() {}; // virtueller Destruktor
virtual void ichBinEinItem() = 0; // pure/abstrakte virtuelle Funktion
protected:
ItemInterface(std::size_t gewicht)
: gewicht_{ gewicht }
{};
std::size_t gewicht_;
// Sobald du eine pure virtuelle Funktion deklarierst, kannst du keine Instanz der Klasse mehr erstellen, da die Funktion überschrieben werden muss. Diese Klassen heißen abstrakte Klassen.
};
class Item1 : public ItemInterface
{
public:
Item1(std::size_t gewicht)
: ItemInterface(gewicht)
{};
virtual void ichBinEinItem() override // "override" spezifiziert, dass diese Funktion eine andere Funktion überschreibt. Falls dies nicht der Fall ist, wird die ein Compilerfehler angezeigt ( C++11 Feature )
{
std::cout << "Ich bin Item Nummer 1. Mein Gewicht ist: " << gewicht_ << " kg.\n"; // benutze "\n" anstelle von std::endl, wenn du viel Text ausgeben lässt ist dies im Optimalfall wesentlich schneller.
}
};
class Item2 : public ItemInterface
{
public:
Item2(std::size_t gewicht)
: ItemInterface(gewicht)
{};
virtual void ichBinEinItem() override
{
std::cout << "Ich bin Item Nummer 2. Mein Gewicht ist: " << gewicht_ << " kg.\n";
}
};
int main()
{
std::vector< std::unique_ptr<ItemInterface> > items;
items.emplace_back(std::make_unique<Item1>(10));
items.emplace_back(std::make_unique<Item2>(20));
for (auto& item : items) { // range-based for loop ( DE? )
item->ichBinEinItem();
}
return 0;
}
Dieser Code generiert den folgenden Text in der Konsole:
Ich bin Item Nummer 1. Mein Gewicht ist: 10 kg.
Ich bin Item Nummer 2. Mein Gewicht ist: 20 kg.
Das Ganze hier ist relativ schnell zusammengewürfelt, wenn also jemand einen Fehler findet - BITTE korrigieren ! Für die deutschen Übersetzungen gibt es übrigens keine Gewähr
EDIT : Hier ist noch ein englischer Spickzettel, den du benutzen kannst, um den richtigen Container für deine Anwendung zu finden.
http://i.stack.imgur.com/G70oT.png