QSet und operator==

Alles rund um die Programmierung mit Qt
Antworten
Superheftig
Beiträge: 63
Registriert: 6. September 2008 15:20

QSet und operator==

Beitrag von Superheftig »

Hallo!

Ich habe ein kleines Problem mit QSet!

Ich will eine eigene Klasse in das Set einfügen:

Code: Alles auswählen

class MyClass {

public:
  int value;
};
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
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Muß man für Pointer überhaupt was bereitstellen? Meldet der Compiler einen Fehler für das QSet?
Superheftig
Beiträge: 63
Registriert: 6. September 2008 15:20

Beitrag 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.
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Dann leg halt im QSet entweder die Values direkt ab, oder so etwas wie den QPointer und mach damit deine Vergleiche.
Superheftig
Beiträge: 63
Registriert: 6. September 2008 15:20

Beitrag von Superheftig »

als wert ablegen geht leider nicht...
dann schau ich mir mal den QPointer an
Superheftig
Beiträge: 63
Registriert: 6. September 2008 15:20

Beitrag 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.
Troll.Soft
Beiträge: 190
Registriert: 18. Juni 2008 09:52
Wohnort: Hamburg

Beitrag 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
Superheftig
Beiträge: 63
Registriert: 6. September 2008 15:20

Beitrag 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
Troll.Soft
Beiträge: 190
Registriert: 18. Juni 2008 09:52
Wohnort: Hamburg

Beitrag 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
Superheftig
Beiträge: 63
Registriert: 6. September 2008 15:20

Beitrag 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.
Troll.Soft
Beiträge: 190
Registriert: 18. Juni 2008 09:52
Wohnort: Hamburg

Bei mir funktioniert es, siehe Code

Beitrag 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
Superheftig
Beiträge: 63
Registriert: 6. September 2008 15:20

Beitrag von Superheftig »

da du das problem immer noch nicht verstanden hast ist eine weitere diskussion relativ sinnlos.
Aber danke für deine bemühungen
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag 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 ...
Antworten