MainWidget mit oder ohne Pointer

Alles rund um die Programmierung mit Qt
Massimo B.
Beiträge: 45
Registriert: 14. Juni 2006 11:05
Wohnort: Bonn, Germany

MainWidget mit oder ohne Pointer

Beitrag von Massimo B. »

Hallo.

Wo besteht der Unterschied für main(), ob ich das MainWidget mit oder ohne Pointer erstelle? Ich habe beide Versionen gesehen:

Code: Alles auswählen

int main(int argc, char *argv[])
{
	QApplication app(argc, argv);
	TripPlanner *tripPlanner = new TripPlanner;
	app.setMainWidget(tripPlanner);
	tripPlannerBase->show();
	return app.exec();
}

Code: Alles auswählen

int main(int argc, char *argv[])
{
	QApplication app(argc, argv);
	TripPlanner tripPlanner;
	app.setMainWidget(&tripPlanner);
	tripPlannerBase.show();
	return app.exec();
}
Zuletzt geändert von Massimo B. am 23. Juni 2006 14:03, insgesamt 1-mal geändert.
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Im ersten Fall wird der Destruktor vom MainWidget nicht aufgerufen
Massimo B.
Beiträge: 45
Registriert: 14. Juni 2006 11:05
Wohnort: Bonn, Germany

Beitrag von Massimo B. »

Wenn main verlassen wird sollte doch auch beim dynamischen Objekt der Destruktor aufgerufen werden, da das Objekt entfernt wird?
Für das Hauptfenster könnte das noch egal sein, aber wann würde ein dynamisch angelegtes Widget Sinn machen?
OscarWild
Beiträge: 54
Registriert: 19. Juni 2006 19:59

Beitrag von OscarWild »

paoleela hat geschrieben:Wenn main verlassen wird sollte doch auch beim dynamischen Objekt der Destruktor aufgerufen werden, da das Objekt entfernt wird?
Ja, trotzdem bleibt es unschön, sich die delete-Zeile zu sparen.
paoleela hat geschrieben:aber wann würde ein dynamisch angelegtes Widget Sinn machen?
Ganz einfach: in allen anderen Fällen. Immer wenn es sich um ein QObject oder ein Derivat davon handelt, das in ein anderes QObject eingehängt wird, darf das Objekt nur dyamisch allokiert werden.
slash-ex
Beiträge: 239
Registriert: 30. März 2005 21:40

Beitrag von slash-ex »

mmh, probier doch einfach mal aus wann der destructor aufgerufen wird! schreib mal eine ausgabefunktion in den destro. mich würde das mal brennend interessieren.
Sym
Beiträge: 139
Registriert: 15. Mai 2006 15:38
Wohnort: Bremen

Beitrag von Sym »

Ich denke, der Speicher wird halt nicht mehr freigegeben.

Warum? Weil Qt von sich aus nur Objekte zerstört, wenn das Parent-Object zerstört wird. In diesem Fall gibt es kein Parent und somit bleibt das Objekt als Zombie im Speicher zurück.

Ist auf jeden Fall bei normalem C++ so.
slash-ex
Beiträge: 239
Registriert: 30. März 2005 21:40

Beitrag von slash-ex »

warte mal, das haben wir gleich, ich bastle zur zeit an meinem RIESIEGEN programm. (sorry fürs großschreiben)
also, gleich erleben wir was Qt alles kann.

mmh interessanterweise bekomme ich bei:

Code: Alles auswählen

int main(int argc, char *argv[])
{
	QApplication app(argc, argv);
	MyBoardWDG *widget;

	widget->resize(width, height);

	widget->show();
	return app.exec();
}
einen speicherzugriffsfehler beim start und bei

Code: Alles auswählen

int main(int argc, char *argv[])
{
	QApplication app(argc, argv);
	MyBoardWDG widget;

	widget.resize(width, height);

	widget.show();
	return app.exec();
}
klappt alles. auf was deutet dieses verhalten. :oops: was habe ich verkehrt gecodet, oh nein ich muss sterben :cry:
Sym
Beiträge: 139
Registriert: 15. Mai 2006 15:38
Wohnort: Bremen

Beitrag von Sym »

Code: Alles auswählen

MyBoardWDG *widget; 
Tja, das kann so auch nicht klappen. Dein Object wird so (da Pointer) nicht richtig instanziiert.

Funktionieren würde es wohl so:

Code: Alles auswählen

MyBoardWDG *widget = new MyBoardWDG;
Allerdings gibst Du das widget später nicht mehr von dem Heap frei. Zu empfehlen ist also Deine zweite Variante.
slash-ex
Beiträge: 239
Registriert: 30. März 2005 21:40

Beitrag von slash-ex »

ach verdammt, stimmt ja. darum wird es auch nicht wieder aufgelöst.
Massimo B.
Beiträge: 45
Registriert: 14. Juni 2006 11:05
Wohnort: Bonn, Germany

Beitrag von Massimo B. »

Dann ist Blanchette's C++ GUI Programming with Qt 3 auch ein schlechtes Beispiel, da wird auf S. 3 für ein "Hello Qt" auch die dynamische Variante ohne delete vorgeführt.
Außerdem ein Zitat von S. 17:
[..]Since we used new to create the dialog’s widgets and layouts,
it would seem that we need to write a destructor that calls delete
on each of the widgets and layouts we created.
But this isn’t necessary, since Qt automatically deletes child
objects when the parent is destroyed, and the objects we allocated
with new are all descendants of the FindDialog.
Burgpflanze
Beiträge: 89
Registriert: 24. Februar 2006 16:41
Wohnort: Dresden

Beitrag von Burgpflanze »

Ich erstelle mein MainWidget mit "new", und setze im Constructor das Attribut "WA_DeleteOnClose":

Code: Alles auswählen

setAttribute(Qt::WA_DeleteOnClose, true);
Somit sollte der belegte Speicher beim Schließen automatisch freigegeben werden.
Massimo B.
Beiträge: 45
Registriert: 14. Juni 2006 11:05
Wohnort: Bonn, Germany

Klassen Member

Beitrag von Massimo B. »

Wie sieht es denn mit members aus?
Z.b. habe ich als member:

Code: Alles auswählen

QTimer progressBarTimer;
QLabel* statusLabel;
Pointer sind schön, wenn ich die member an Objekte mitgeben möchte.
Mit new kann ich auch gleich dem member-CTor Parameter mitgeben, wie

Code: Alles auswählen

statusLabel = new QLabel(" Status ", this);
...aber das könnte ich auch im CTor per Liste initialisieren.

Generell sollte somit für lokale Member gleich sein, ob sie statisch oder dynamisch erzeugt werden, oder?
Gentoo (x86,ppc), KDevelop, Qt3, Qt4
OscarWild
Beiträge: 54
Registriert: 19. Juni 2006 19:59

Re: Klassen Member

Beitrag von OscarWild »

paoleela hat geschrieben:Generell sollte somit für lokale Member gleich sein, ob sie statisch oder dynamisch erzeugt werden, oder?
Siehe weiter oben! Statisch gehts gewaltig in die Hose, wenn das Memeber ein QObject ist, und in ein anderes QObject eingehängt wird, z.B. ein QLabel in ein QLayout; spätestens bei der Destruktion zerstört dann das Parent-QObjekt das QLabel, anschließend versucht der Destruktor der eigenen Klasse, das QLabel nochmals zu zerstören, was zu nicht immer reproduzierbaren Abstürzen führt.
Am besten einfach mal ausprobieren, das Aha-Erlebnis folgt sofort ;-)
Massimo B.
Beiträge: 45
Registriert: 14. Juni 2006 11:05
Wohnort: Bonn, Germany

Beitrag von Massimo B. »

Somit ist der Timer statisch aber erstmal ok?

Warum das einen Absturz gibt, versteh ich dennoch nicht ganz. Der Parent des QLayout ist das Fenster. Wird das Fenster zerstört, wird das QLayout zerstört, und das zerstört wieder rum das child QButton.
Dass alle QObject-Erben sind, hat doch keinen Einfluß, oder?
Gentoo (x86,ppc), KDevelop, Qt3, Qt4
OscarWild
Beiträge: 54
Registriert: 19. Juni 2006 19:59

Beitrag von OscarWild »

paoleela hat geschrieben:Somit ist der Timer statisch aber erstmal ok?
ja.
paoleela hat geschrieben:Warum das einen Absturz gibt, versteh ich dennoch nicht ganz. Der Parent des QLayout ist das Fenster. Wird das Fenster zerstört, wird das QLayout zerstört, und das zerstört wieder rum das child QButton.
Dass alle QObject-Erben sind, hat doch keinen Einfluß, oder?
Doch - wird ein QObject zerstört, zerstört es automatisch alle seine Kinder! Nehmen wir mal folgendes an:

Code: Alles auswählen

Class Test:public QWidget
{
  QPushButton my_button;
}

...

Test::Test()
{
  addWidget(&my_button);
}

...

int main()
{
  Test my_test;
}
Folgendes passiert nun bei der Destruktion:
- das my_test zugrundeliegende QObject zerstört zunächst automatisch my_button, da my_button per addWidget() dort eingehängt wurde.
- anschließend gibt der Destruktor ~Test() den gesamten Speicherbereich der Instanz frei, inkl. dem Bereich, den my_test belegt hatte - obwohl my_test bereits tot ist!

Ich hoffe, das ist jetzt einigermaßen verständlich gewesen.

Sinn der Sache ist, dass man sich nicht mehr ums Aufräumen der kind-Objekte kümmern muss - was man wirklich schätzen lernt, wenn die Oberfläche dynamisch aufgebaut wird. An diesem Punkt scheinen übrigens regelmäßig Leute hängen zu bleiben, manche beschweren sich sogar heftigst, weil sie den Sinn nicht verstehen, und zwar nicht nur in diesem Forum (schaut mal z.B.
hier, da ist das Verhalten auch nochmal beschrieben, insb. auch der englische Text!)
Antworten