QList und eigenes Objekt?

Du bist neu in der Welt von C++? Dann schau hier herein!
gast23
Beiträge: 103
Registriert: 11. August 2010 10:43

QList und eigenes Objekt?

Beitrag von gast23 »

Hi,

ich habe eine eigene Klasse Person die 3 QStrings beinhaltet...

Diese Personen Objekte werden auf dem Heap angelegt und dann wird ein Pointer in eine QList abgelegt...

Wie lösche ich die die Personen Objekte sauber?

Also ich verschicke einen Pointer auf die QList<Personen *>* und was muss ich tun wenn ich die QList nicht mehr benötige?

Reicht ein einfacher Methoden aufruf? clear()? Oder msus ich über die Liste laufen und den Pointern folgen und die Objekte selbst löschen?

Danke
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Warum überhaupt auf den Heap per new?
Die Liste speichert nur Pointer - wenn Du die Liste löscht, werden also nicht die Objekte gelöscht.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
gast23
Beiträge: 103
Registriert: 11. August 2010 10:43

Beitrag von gast23 »

Die Objekte werden in einer Funktion gebaut...

Man darf doch keine Objekte lokal anlegen... die gehn doch dann nach Funktionsende kaputt und der Pointer zeigt an eine Stelle die nicht mehr da ist...

?!
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Die prinzipielle Frage vorweg: Müssen im Container wirklich Zeiger liegen? Reichen dir Values nicht? Zeiger solltest du wirklich nur verwenden, wenn deine Anforderungen darauf bestehen, dass die Zeiger im Programm rumgereicht werden können. Und hier reicht in vielen Fällen auch eine (konstante) Referenz.
Und das "*" am Ende ist Absicht, dein QList-Objekt liegt im HEAP? Das solltest du umgehend ändern!

Zur Frage:
Ein Container zerstört selber schon die Objekte die drin liegen. Nur ist ein Zeiger halt etwas spezielles. Zerstöre ich ein Pointer-Objekt, zerstört das nur nicht das, auf was der Pointer zeigt. Deshalb werden die eigentlichen Objekte, die hinter den Zeigern im Container liegen, nicht zerstört (im Destruktor, clear(),...) - das klassische Speicherleck.
Zum Zerstören entweder selber durchiterieren+delete, oder gleich qDeleteAll() verwenden.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

gast23 hat geschrieben:Die Objekte werden in einer Funktion gebaut...

Man darf doch keine Objekte lokal anlegen... die gehn doch dann nach Funktionsende kaputt und der Pointer zeigt an eine Stelle die nicht mehr da ist...

?!
Korrekt. Aber Christian meinte die Elemente selber im Container (wie ich auch): müssen die wirklich dynamisch erstellt werden? Wenn du Values reinnimmst, landen Kopien im Container, du bekommst keine Probleme beim Dereferenzieren.
gast23
Beiträge: 103
Registriert: 11. August 2010 10:43

Beitrag von gast23 »

Ich würde das Löschen der Liste sowie das Löschen der Objekte übernehmen...

Code: Alles auswählen

QList<Person> Klasse::methode() {

QList<Person> personen;

peronen.???

}
Also am liebsten wäre mir wenn die Liste und die Objekte copy per value rausgehen damit nie ein Speicherleck entstehen kann jedoch ist mir nicht klar wie das funktionieren soll...?

Wenn ich doch eine PErson anlege ist diese doch lokal...

Code: Alles auswählen

Person p("name","vorname");
gast23
Beiträge: 103
Registriert: 11. August 2010 10:43

Beitrag von gast23 »

franzf hat geschrieben: Wenn du Values reinnimmst, landen Kopien im Container, du bekommst keine Probleme beim Dereferenzieren.
Wie mache ich das?

Code: Alles auswählen

QList<Person> bla() {

QList<Person> out;

Person a("name","vorname");

out.append(a);

return out;

}
So???
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Was willst du denn erreichen? Wenn du einfach nur ne Preson hinzufügen willst, gib deiner Klasse eine entsprechende Methode:

Code: Alles auswählen

class Klasse {
    QList<Person> personen_;
public:
    void addPerson(const Person& person) {
        if(person.isValid())  // ein kurzer Check, ob wir das Objekt überhaupt aufnehmen wollen
            personen_.append(person);
    }
};

// Verwendung:
Klasse k;
Person p;
k.addPerson(p);
Du schlägst mehrere Fliegen mit einer Klappe:
*) Kapselung (deine Member sind nicht public)
*) Der Benutzer deiner Klasse braucht sich nicht um deren Innereien zu kümmern
*) Du hast volle Kontrolle über den Zustand deiner Objekte.
*) Du brauchst gar nix mehr selber zerstören!

// edit:
So???
Ja, so landen Kopien in einem Container, und dein Container geht auch per Kopie raus.
gast23
Beiträge: 103
Registriert: 11. August 2010 10:43

Beitrag von gast23 »

Hi,

danke!

Ich brauche wirklich nur etwas ganz simples...

Das schreiben einer extra Container Klasse wäre schon wieder viel zu viel...

Aber eine kurze Frage dazu:

k.addPerson(p);

und dann einfach

return k;

Dann würde auch alles kopiert oder bräuchte man dann noch extra Operatoren?
gast23
Beiträge: 103
Registriert: 11. August 2010 10:43

Beitrag von gast23 »

franzf hat geschrieben: Ja, so landen Kopien in einem Container, und dein Container geht auch per Kopie raus.
Ich würde die Methode quasi so nutzen bzw. die QList per Signal verschicken...

Code: Alles auswählen

void Obj::einSlot(QList<Person> p) {

//Etwas mit p tun

//Fertig

}
Also theoretisch sind doch danach alle Objekte weg?
kater
Beiträge: 306
Registriert: 29. Dezember 2009 01:13
Wohnort: Darmstadt

Beitrag von kater »

franzf hat geschrieben: Zum Zerstören entweder selber durchiterieren+delete, oder gleich qDeleteAll() verwenden.
thx
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

gast23 hat geschrieben:Also theoretisch sind doch danach alle Objekte weg?
Ja, aber nur die deines funktionslokalen Objektes. Dank implicit sharing wird aber wohl nichts zerstört, sondern nur detach()ed.
Beschäftige dich nochmal mit dem Gültigkeitsbereiche von Variablen. Hakt es da vllt. noch?
gast23
Beiträge: 103
Registriert: 11. August 2010 10:43

Beitrag von gast23 »

Ja das sage ich doch die ganze Zeit...

In dem Methode die das signal auslößt wird nun die QList lokal angelegt und die Objekte wie du gesagt hast in die Liste per value kopiert...

Mit emit wird dann in der Methode das signal ausgelößt.

Der Slot der auf das signal reagiert bekommt eine Kopie der Liste...

Mit der Kopie kann ich etwas machen... und wenn der slot durchlaufen ist, ist auch die Kopie die über das signal als parameter gekommen ist auch weg.... ODER nicht?!

Normal doch schon

es wird beim return 1xkopiert + Löschung da der Scope verloren geht + Kopie bei Slot parameter + Löschung nachdem der Slot durchlaufen ist...

?
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Du hast mit Pointern angefangen, weil die den Scope überleben, und es wurde so viel gesagt... Und du hast wohl echt noch Schwierigkeiten mit der Einschätzung, was wann wie zerstört wird, weil du so oft weiter gefragt hast, deshalb kam auch nochmal der Hinweis nach "Gültigkeitsbereich" zu lesen.

Und ein "signal auslösen" hat rein gar nix mit "return" zu tun -> Kapitel SIGNALS and SLOTS in der Doku. Schau dir auch mal an, was dir eine const-Referenz als Parameter bringt.
Ich weiß ehrlich gesagt nicht, warum du die ganze Liste weitergeben willst. Ich dachte du willst nur eine Person hinzufügen? Reicht es da nicht, die Umwelt über die neue Person zu informieren?

Was willst du jetzt konkret modellieren/erreichen/..., damit man deine Lösung optimieren kann?
gast23
Beiträge: 103
Registriert: 11. August 2010 10:43

Beitrag von gast23 »

Ich möchte eine Liste von Personen direkt als Signal verschicken also im Parameter des Signals (Copy per value).

Zuerst wollte ich alles auf dem Heap erledigen und nur einen Pointer auf die Liste mit den Personen als Signal verschicken jedoch bin ich nicht sicher ob überhaupt jemand das Signal erhält, folglich sind die Pointer verloren... => Speicherleck.... Da diese Personen Liste periodisch erzeugt wird und die Hardware alles andere als performant ist, kann ich auch nichts zwischenspeichern...
Antworten