Seite 1 von 1

QPtrList durchsuchen?

Verfasst: 20. April 2005 18:17
von Notwist
Hallo,

weiß jemand, ob es eine Möglichkeit gibt, eine verkettete Liste vom Typ QPtrList nach einem Variablen-Wert eines Eintrages zu durchsuchen und den Index zurückgeben zu lassen, um ihn zB zu löschen?

Mache das im Moment so:

Code: Alles auswählen

QPtrList<CanData> candataList;
CanData *candata;

void MyContainer::eraseIdEntry(int ident)
{
	for (candata=canDataList.first(); candata!=0;candata=canDataList.next())
	{
		if (candata->id==ident)
		{
			canDataList.setAutoDelete(TRUE);
			canDataList.remove();
			canDataList.setAutoDelete(FALSE);
		}
	}	
}
Dachte, das geht irgendwie mit find(), aber irgendwie kann man da auch nicht nach den Variblen in den Einträgen suchen.

Verfasst: 21. April 2005 08:45
von FlorianBecker

Code: Alles auswählen

QPtrList<Employee> list;

    list.append( new Employee("John", "Doe", 50000) );
    list.append( new Employee("Jane", "Williams", 80000) );
    list.append( new Employee("Tom", "Jones", 60000) );

QPtrListIterator<Employee> it( list );
    Employee *employee;
    while ( (employee = it.current()) != 0 ) {
        ++it;
        cout << employee->surname().latin1() << ", " <<
                employee->forename().latin1() << " earns " <<
                employee->salary() << endl;
    }
Das kennst du, oder? Was du mit iterators machst weisst du auch? Dann kannst du nämlich jedes item innerhalb der liste steuern, ansprechen, auslesen, löschen, was auch immer.

Zu dem find, mh, keine Ahnung, QStringList hingegen hat findIndex und hier geht das find nämlich auch nicht so, wie ich mir das vorgestellt hatte.

Nunja, ich hoffe, ich konnte vielleicht helfen.

Verfasst: 21. April 2005 10:32
von Notwist
Hallo,

wo ist der Vorteil der Iteratoren gegenüber meiner for-Schleife? Die einzelnen Varaiblen kann ich ja auch mit meiner for-Schliefe ansprechen. Ein Vorteil ist, glaub ich, dass man mehrere Iteratoren gleichzeitig laufen lassen kann. Wie würde das in der praktischen Anwendung aussehen?

Verfasst: 21. April 2005 10:50
von FlorianBecker
Using a list iterator is a more robust way of traversing the list than using the QPtrList member functions first(), next(), current(), etc., as many iterators can traverse the same list independently.

Aber es steht dazu eine menge Text unter:
http://doc.trolltech.com/3.3/qptrlistiterator.html

Verfasst: 21. April 2005 11:42
von Notwist
Was mir beim Abändern meiner for-Schleifen in QPtrIteratoren aufgefallen ist, ist, dass meine Erase-Methode jetzt nur noch mit der find-Funktion funktioniert:

Code: Alles auswählen

void MyContainer::eraseIdEntry(int ident)
{
	QPtrListIterator<CanData> it( canDataList ); 
	while ( (candata = it.current()) != 0 )  
	{
		++it;
		if (candata->id==ident)
		{
			int index = canDataList.find(candata); 
			canDataList.setAutoDelete(TRUE);
			canDataList.remove(index);
			canDataList.setAutoDelete(FALSE);
		}
	}	
}
Muss irgendwas mit der Iteratoren-Eigenart zu tun haben, dass sie, sobald ein Item gelöscht wurde, auf das current-item zeigen. Eigentlich hatte ich das ++it; aber dafür in it++; geändert und nach unten, unter den Löschvorgang gebracht, was aber keine Lösung brachte. Kann mir das jemand erklären?

Verfasst: 21. April 2005 12:02
von Goos
Och nun lies doch einfach mal in der Doku unter QPtrListIterator, da steht das beschrieben. :)

Goos

Verfasst: 21. April 2005 12:05
von FlorianBecker
Danke!

Verfasst: 21. April 2005 12:36
von Notwist
Hallo Jungs,

sorry, wenn das nervt. geht ja nicht darum, dass ich die nicht lese, sondern nicht verstehe, warum das so ist. Die obigen Fragen waren nen bisschen dumm, gebe ich zu, aber die letzte hatte ja was mit Verständnis zu tun. Schließlich zeigt der Iterator nach dem Löschen auf currentItem(). Das hat aber doch nichts damit zu tun, warum er das gefundene Objekt nicht löscht.

1. Finde das Objekt mit dem Wert
2. wenn gefunden, remove() -> löscht das Objekt, auf das es zeigt
3. Iterator zeigt nun auf currentItem, also das Objekt vor dem gelöschten Objekt, denk ich (er löscht aber eben dies nicht, sondern wirr)

Hätte doch so klappen müssen. Eine Lösung auf meine Frage steht dabei nicht in der Doku! ;-)

Naja, läuft ja so mit find(). Danke trotzdem.

Verfasst: 21. April 2005 12:56
von Goos
Notwist hat geschrieben:(er löscht aber eben dies nicht, sondern wirr)
Wieso sollte dein Iterator auch irgendwas loeschen, wo doch in der Doku steht, dass Iteratoren deine Liste in keinster Weise veraendern?

Goos

Verfasst: 21. April 2005 13:49
von Notwist
Nein, der Iterator nicht, das ist klar. Der zeigt ja nur auf den Eintrag, das soll er ja auch. Aber remove(); löscht den Eintrag, auf den er zeigt. Sollte er jedenfalls. Löscht aber eben nicht den, worauf ich denke, dass der Iterator zeigt. Verwirrend, ich weiß!

Verfasst: 21. April 2005 14:02
von Goos
QPtrListIterator hat halt keine remove() Methode.
Dein remove() loescht also auch nicht das Item auf welches dein Iterator zeigt. Klingt doch irgendwie logisch, oder?
Dein Iterator zeigt halt wirklich nur auf die Liste und macht sonst gar nichts, er veraendert nichtmal dein currentItem.
Die einzige direkte Verbindung zwischen Iterator und Liste besteht halt darin, dass all deine Iteratoren auf deiner Liste nach einem remove() auf das currentItem gesetzt werden. Das passiert, weil sonst die Chance bestuende, dass einer der Iteratoren noch auf das soeben geloeschte Element zeigt.

Goos