Seite 1 von 1
QSet und operator==
Verfasst: 18. Juni 2009 18:12
von Superheftig
Hallo!
Ich habe ein kleines Problem mit QSet!
Ich will eine eigene Klasse in das Set einfügen:
Jetzt erstelle ich mein QSet:
Code: Alles auswählen
QSet<MyClass*> set;
MyClass* myClass = new MyClass();
set.contains(myClass);
Nun will ich überprüfuen ob das gerade erstellte Objekt bereits in dem Set vohanden ist. Dabei sollen zwei MyClass Objekte gleich sein wenn sie den gleichen int value haben. Dafür würde ich jetzt nen operator== implementieren:
Code: Alles auswählen
bool operator==(const MyClass& myClass1, const MyClass& myClass2) {
return myClass1.value == myClass2.value;
}
Das Problem ist aber das ja ein pointer verlgiech gemacht wird da sowohl das QSet als auch das übergebene myClass Object pointer sind. Wie schaffe ich es jetzt den Vergleich richtig zu machen.
Code: Alles auswählen
bool operator==(MyClass* myClass1, MyClass* myClass2);
}
Den operator mit pointern kann man ja nicht implementieren
Verfasst: 18. Juni 2009 18:22
von upsala
Muß man für Pointer überhaupt was bereitstellen? Meldet der Compiler einen Fehler für das QSet?
Verfasst: 18. Juni 2009 18:25
von Superheftig
ne das ganze läuft.
wenn die contains method aufgerufen wird verlgeicht das qset die speicheradresse von dem myClass objekt, dass übergeben wird, mit den speicher addressen der objekte die im set drin sind.
Ich will aber dass die Objekte anhand ihrer int values verglichen werden.
Verfasst: 18. Juni 2009 18:31
von upsala
Dann leg halt im QSet entweder die Values direkt ab, oder so etwas wie den QPointer und mach damit deine Vergleiche.
Verfasst: 18. Juni 2009 18:38
von Superheftig
als wert ablegen geht leider nicht...
dann schau ich mir mal den QPointer an
Verfasst: 19. Juni 2009 15:06
von Superheftig
So hab das ganze mit ner dummy klasse wie qpointer gelöst.
Funktionieren QSet und QHash also mit Pointern nicht? Außer man will wirklich nur die Pointer vergleichen die drin gespeichert sind was ja so gut wie nie der fall ist.
Problem war bei mir, dass ich die Klasse nicht als wert einfügen konnte, weil sie wie bei QWidget nicht kopiert werden kann/soll.
Verfasst: 19. Juni 2009 21:00
von Troll.Soft
Superheftig hat geschrieben:
Funktionieren QSet und QHash also mit Pointern nicht? Außer man will wirklich nur die Pointer vergleichen die drin gespeichert sind was ja so gut wie nie der fall ist.
Alle Qt-Container funktionieren superheftig mit Pointern. Es ist den Containern schnurz egal, ob Pointer oder direkte Objekte.
Dein Problem liegt bei C++. Wenn Du nicht die Pointer, sondern die Objekte vergleichen willst, mußt Du die Pointer dereferenzieren.
Also
Code: Alles auswählen
if ( *x1 == *x2 ) // vergleicht die Ob jekte
alles ok;
else
mist, alles falsch;
if ( x1 == x2 ) // vergleicht die Pointer
alles ok;
else
mist, alles falsch;
machs mal so
tschüß
Trollsoft
Verfasst: 23. Juni 2009 13:39
von Superheftig
was der container intern verlgeicht hab ich ja leider nicht in der hand. der ruft ja automatisch den operator auf dann kann ich nichts dereferenzieren
Verfasst: 24. Juni 2009 08:37
von Troll.Soft
Superheftig hat geschrieben:was der container intern verlgeicht hab ich ja leider nicht in der hand. der ruft ja automatisch den operator auf dann kann ich nichts dereferenzieren
Hm, der Container ruft den Vergleichsoperator auf, den Du definierst. Also hast Du es im Griff, wie verglichen werden soll.
tschüß
Troll.Soft
Verfasst: 24. Juni 2009 11:51
von Superheftig
ja aber er ruft den falschen auf...wie oben beschrieben...
Code: Alles auswählen
bool operator==(MyClass* myClass1, MyClass* myClass2);
kann man in c++ nicht überschreiben. Das QSet ruft also die standardimplementierung des Operators auf und vergleicht die speicher addressen ungefährt so
Code: Alles auswählen
bool operator==(MyClass* myClass1, MyClass* myClass2) {
return myClass1 == myClass2;
}
funzt also nicht.
Bei mir funktioniert es, siehe Code
Verfasst: 24. Juni 2009 16:15
von Troll.Soft
Hallo,
untenstehender Code tut genau das, was er tun soll. Probier es bitte selber aus. Mit der Klasse kannst Du jeden beliebigen Container füllen. Egal of Qt oder STL oder Boost etc.
Code: Alles auswählen
class MyClass {
public:
MyClass(int Value) : Value(Value) {}
friend bool operator==(const MyClass& myClass1, const MyClass& myClass2)
{
return myClass1.Value == myClass2.Value;
}
private:
int Value;
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MyClass Class1(11);
MyClass Class2(22);
MyClass* Class3 = new MyClass(11);
if ( Class1 == Class2 )
qDebug() << "Class1 == Class2";
else
qDebug() << "Class1 != Class2";
if ( Class1 == *Class3 )
qDebug() << "Class1 == Class3";
else
qDebug() << "Class1 != Class3";
return app.exec();
}
tschüß
Troll.Soft
Verfasst: 24. Juni 2009 16:44
von Superheftig
da du das problem immer noch nicht verstanden hast ist eine weitere diskussion relativ sinnlos.
Aber danke für deine bemühungen
Verfasst: 24. Juni 2009 17:43
von RHBaum
was der container intern verlgeicht hab ich ja leider nicht in der hand. der ruft ja automatisch den operator auf dann kann ich nichts dereferenzieren
QSet baut intern nen Hash auf .... eine definition wie es den hash und was fuer einen verwendet, ist nicht definiert ...
Damit kannst den auch ned ueberschreiben, und alle Ideen die auf annahmen beruhen die ned in der QTDoku stehen sind damit ned wirklich stabil ^^
Fazit: verwende std::set und ueberschreib den "<" operator.
Prinzipiell, HashSuchlisten und Baueme brauchen eine "Order". Also langt ein vergleich auf gleichheit nie aus, sondern er braucht kleiner.
Mit vertauschung der parameter kriegt er ueber den < operator auch das groesser und gleich und ungleich raus ...
Also wenn bei sowas auf operatoren geschossen wird, dann sicher ned aufs ==
@Troll.Soft
Das dein code funktioniert, muss zufall sein ^^ zumindest wenn du damit effekte in dem QSet erzielst ^^ und das war die frage des threaderstellers ^^
Ciao ...