Highscore-Klasse
-
Warum fängt die Methode getHighscore mit einem kleinen g an und die Methode AddnewEntry mit einem großen a? Und warum ist das n bei new klein? "addnew" ist kein englisches Wort, das sind zwei Wörter, also sollte es AddNew sein.
Ich vote übrigens für addNewEntry statt GetHighscore

Außerdem würde ich etwas mehr Arbeit investieren und nicht einfach die Datenstruktur in der die Highscores gespeichert werden zurückgeben, sondern die einzelnen Einträge bzw. einen Iterator mit dem man diese durchgehen kann.
Außerdem würde ich einen op<< und op>> hinzufügen um die Highscore bequem speichern und laden zu können
Ebenso einen Konstruktor der einen std::istream entgegen nimmt und aus diesem die Highscore lädt.
-
Nexus schrieb:
Da verwechselst du was.
std::listist eine doppelt verkettete Liste, also ein sequenzieller und kein assoziativer Container. Da wird auch nichts automatisch sortiert, sonst wären wohl Methoden wiepush_front()undpush_back()relativ sinnlos.Mir ist klar, dass die Liste nicht automatisch sortiert wird, nur da ich den neuen Eintrag immer sofort sortiert einfüge, liegt sie immer sortiert vor und sie nie unsortiert, also muss auch nichts sortiert werden.
Nexus schrieb:
Vielleicht noch eine Funktion zum Zurücksetzen der Highscore.
Jo, das könnte noch mit aufgenommen werden.
S.T.A.L.K.E.R. schrieb:
Außerdem würde ich etwas mehr Arbeit investieren und nicht einfach die Datenstruktur in der die Highscores gespeichert werden zurückgeben, sondern die einzelnen Einträge bzw. einen Iterator mit dem man diese durchgehen kann.
Außerdem würde ich einen op<< und op>> hinzufügen um die Highscore bequem speichern und laden zu können
Ebenso einen Konstruktor der einen std::istream entgegen nimmt und aus diesem die Highscore lädt.Jo, werde ich auch versuchen mit zu implementieren.
Mache mich gleich mal dran, weiter an der Klasse zu arbeiten.
Schreibe dann später wieder die aktuelle Version.MfG
Hundefutter
-
Darf ich ein zwei Vorschläge anbringen?
class HighscoreEntry { private: std::string m_name; long m_timestamp; long m_points; public: HighscoreEntry(std::string const& name, long points, long timestamp) : m_name(name) , m_points(points) , m_timestamp(timestamp) { } ~HighscoreEntry() { }; public: std::string const& get_name() const { return m_name; }; void set_name(std::string const& name) { m_name = name; }; long get_timestamp() const { return m_timestamp; }; void set_timestamp(long timestamp) { m_timestamp = timestamp; }; long get_points() const { return m_points; }; void set_points(long points) { m_points = points; }; }; inline bool operator <(HighscoreEntry const& left, HighscoreEntry const& right) { return (left.get_points() == right.get_points() ? left.get_name().compare(right.get_name()) < 0 : left.get_points() < right.get_points()); } typedef std::multiset<HighscoreEntry> Highscore_t; inline void write_highscore(std::string const& path, Highscore_t const& highscore) { /* Schreibfunktion */ } inline void read_highscores(std::string const& path, Highscore_t& highscore) { highscore.clear(); /* ... lese die Highscore ... */ }Wäre meiner Meinung nach am einfachsten, nicht?
std::multisetübernimmt auch die Sortierung deiner Einträge voll automatisch und sortiert sie schneller ein, als deinestd::listdas kann. Denn du musst die Liste sequentiell durchlaufen, um den Eintrag zu platzieren.Grüssli
-
Hui, das ist ja schon fast eine komplette Lösung..
Danke für deine Mühe.
Finde die Lösungsart sehr gut und werde es nun selbst versuchen ähnlich zu implementieren. Ich merke selbst, dass mir noch sehr viel Übung fehlt, gerade im Umgang mit der STL..
Also versuche ich das Ganze erstmal selbst, kann mir ja dann deine Lösung hier angucken, falls ich nicht weiterkomme.Vielen Dank an alle für die Hilfen.
MfG
Hundefutter
-
Ich habe jetzt für mich so eine Klasse geschrieben, deren Objekte Einträge der Highscore sind.
Nun habe ich versucht, mit multiset zu arbeiten, nur irgendwie läuft bei mir der insert-Befehl nicht.std::multiset<HighscoreEntry> Highscore; //multiset vom Typ HighscoreEntry std::multiset<HighscoreEntry>::iterator it; //entsprechender Iterator std::string name; int points; std::cout << "Name: "; std::cin >> name; std::cout << "Punkte: "; std::cin >> points; HighscoreEntry Entry(name, points); //Instanz der Klasse Highscore.insert(Entry); //Zeile, die den Fehler verursachtBeim Kompilieren meckert er (siehe unten).
Kann es sein, dass der Vergleichstyp hier noch nicht definiert ist? Der Container muss ja nach einem bestimmten Kriterium sortiert werden und ich denke mir, er weiß bei dem Typ nicht, wie er es machen soll...Hier die Fehlerausgabe:
make -k all
Building file: ../main.cpp
Invoking: GCC C++ Compiler
g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"main.d" -MT"main.d" -o"main.o" "../main.cpp"
/usr/include/c++/4.1.3/bits/stl_function.h: In member function »bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = HighscoreEntry]«:
/usr/include/c++/4.1.3/bits/stl_tree.h:857: instantiated from »typename std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::insert_equal(const _Val&) [with _Key = HighscoreEntry, _Val = HighscoreEntry, _KeyOfValue = std::_Identity<HighscoreEntry>, _Compare = std::less<HighscoreEntry>, _Alloc = std::allocator<HighscoreEntry>]«
/usr/include/c++/4.1.3/bits/stl_multiset.h:310: instantiated from »typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, typename _Alloc::rebind<_Key>::other>::const_iterator std::multiset<_Key, _Compare, _Alloc>::insert(const _Key&) [with _Key = HighscoreEntry, _Compare = std::less<HighscoreEntry>, _Alloc = std::allocator<HighscoreEntry>]«
../main.cpp:20: instantiated from here
/usr/include/c++/4.1.3/bits/stl_function.h:227: Fehler: no match für »operator<« in »__x < __y«
make: *** [main.o] Fehler 1
make: Das Target »all« wurde wegen Fehlern nicht aktualisiert.
Build complete for project Highscore-KlasseWas meint ihr dazu? Wo liegt hier noch der Fehler?
MfG
Hundefutter
-
Steht ja in der Fehlermeldung, obwohl die wirklich sehr mühsam sind, die GCC-Fehlermeldungen:
Fehler: no match für »operator<« in »__x < __y«
Also der
operator <fehlt für die KlasseHighscoreEntry. Du musst also einen entsprechendenoperator <definieren. Ein Beispiel dafür siehst du in meinem Beispiel oben
Grüssli
-
Ich habe nun mal versucht, deine Definition des Operators einzufügen:
inline bool operator <(HighscoreEntry const &left, HighscoreEntry const &right);Nun sagt er mir aber immer, dass die Funktion nur ein Element nehmen darf:
../HighscoreEntry.h:18: Fehler: »bool HighscoreEntry::operator<(const HighscoreEntry&, const HighscoreEntry&)« muss genau ein Argument nehmenWarum sagt der das?
-
Ich habe den
operator <ausserhalb der Klasse definiert, wie man es bei diesen Operatoren oft macht. Du dagegen, hast denoperator <in der Klasse definiert. Wenn du ihn in der Klasse definierst, dann hast du als erster Wertthis, also das eigentliche Objekt und als zweiter Wert, den übergebenen wert. Wenn du noch einen zweiten Parameter definierst, hättest du eigentlich 3 Werte zum vergleichen, was mit demoperator <nicht geht. deshalb die Fehlermeldung.Also entweder raus aus der Klasse damit oder wenn du ihn in der Klasse behälst, dann einen Parameter weniger und mit
thisvergleichen.Grüssli
-
Ach klar, dummer Fehler...

Naja, dann ist ja alles klar.
Danke für die Hinweise.
MfG
Hundefutter
-
Also das hier ist schon mal blödsinn
bool getEntry(int num, std::string &name, T &value, unsigned int ×tamp){
if (list.size() <= num) return false;name = ...
value = ...
timestamp = ...return true;
}das muss so aussehne
string getEntry(int num, std::string &name, T &value, unsigned int ×tamp){
if (list.length() <= num) return true;name = ...
value = ...
timestamp = ...return 0;
}