11
votes

Destructeurs à Qt4

Je suis très confus à propos de l'utilisation des destructeurs à Qt4 et j'espère que vous pouvez m'aider.
Quand j'ai une méthode comme celle-ci (avec "des" est une classe): xxx

Comment puis-je vous assurer que ce widget va être supprimé après sa fermeture?

et en classe "des" J'ai ceci: xxx

où et comment dois-je supprimer * push and * mise en page? Que devrait être dans le destructeur des :: ~ des ()?


0 commentaires

5 Réponses :


2
votes

Dans la plupart des cas, vous devez créer des widgets sur la pile: xxx

De cette façon, ils sont supprimés lorsqu'ils deviennent hors de portée. Si vous voulez vraiment les créer sur le tas, alors il est de votre responsabilité d'appeler de les supprimer quand ils ne sont plus nécessaires.


4 commentaires

C'est un peu plus complexe que ça. QT déclenchera la destruction de certains objets dans certaines situations (s'ils sont enregistrés auprès d'un parent) et, donc, les avoir pile alloués tuerait l'application avec un double libre.


Dribesas, je pense que lorsqu'un QOBJECT est détruit, il est automatiquement désenregistré du parent.


J'utilise une allocation de pile avec QOBjects tout le temps et cela fonctionne bien. Merci pour la descente non informée.


@RPG: Oui, le point est que le parent ne doit pas être supprimé lorsque l'enfant existe ou que vous devez vous assurer que le parent ne possède pas de propriété.




21
votes

qt utilise ce qu'ils appellent arbres d'objet et c'est un peu différent de celui de L'approche typique Raii.

Le qObject classe Constructeur prend un pointeur sur un parent QOBJECT . Lorsque ce parent QOBJECT est destructiré, ses enfants seront également détruits. Il s'agit d'un modèle assez répandu dans les classes de QT et vous remarquerez que beaucoup de constructeurs acceptent un paramètre * parent .

Si vous regardez une partie du qt Exemple de programmes Vous constaterez qu'ils construisent la plupart des objets QT sur le tas et profitent de cet arbre d'objet pour gérer la destruction. J'ai personnellement trouvé cette stratégie utile également, car les objets d'interface graphique peuvent avoir une durée de vie particulière.

qt ne fournit aucune garantie supplémentaire au-delà de la norme C ++ si vous n'utilisez pas qObject ou une sous-classe de qobject (tel que qwidget ).


Dans votre exemple particulier, rien ne garantit que rien ne soit supprimé.

Vous voudrez quelque chose comme ceci pour des (supposer des est une sous-classe de qwidget ): xxx

et vous utiliseriez la classe des comme: xxx


4 commentaires

Ok c'est très utile, mais j'ai une question supplémentaire: lorsque je viens de fermer ce widget appelé "test", cela ne signifie pas que cela sera également détruit, n'est-ce pas? Je dois le détruire / le supprimer pour moi-même. Comment dois-je faire ça?


Si le widget n'a pas de vie propre et qu'aucun des parents avec lequel l'associer, la meilleure option consiste à utiliser la fonctionnalité de suppression rapprochée selon laquelle Cjhuititt mentionne une autre réponse.


Juste pour la clarification, si nous faisons le "bouton-poussoir" en tant que variable membre, alors devons-nous supprimer le bouton-poussoir manuellement au destructeur de widget ou être supprimé lorsque le parent est supprimé ..


Si vous avez un qpushbutton * en tant que variable de membre et donnez-lui un parent approprié (avec son constructeur ou avec setparent () ) il sera supprimé lorsque le parent est supprimé. Vous pouvez également utiliser un clair qpushbutton (et laissez les règles de destruction C ++ standard à lancer), mais vous constaterez probablement que pour beaucoup de choses d'interface graphique QT, vous voudrez un parent de toute façon.



5
votes

La réponse de Richardwb est une bonne solution - mais l'autre approche consiste à utiliser la fente de suppression, comme: xxx

évidemment le signal fermé () peut être remplacé par le signal que vous voulez.


2 commentaires

Il n'y a pas de signal (fermé ()) pour ce widget. Les signaux sont: CustomContextMeneuléStemisteté (Qpoint), détruit () et détruit (QObject *)


Ok, bien, c'était conçu comme un concept général, plutôt qu'un exemple concret. Peut-être que vous pouvez ajouter un signal qui est émis lorsque votre objet termine son travail? C'est un modèle utile de toute façon, cela vous permet de créer quelque chose et de l'oublier, à condition de ne pas conserver aucune référence à cela et que cela finit par finir.



12
votes

Une autre option d'utilisation de Supprimer () CODE> ou des parents, consiste à utiliser la fonctionnalité supprimée pour les widgets. Dans ce cas, QT supprimera le widget lorsqu'il sera fait être affiché.

Des *test = new Des;
test->setAttribute( Qt::WA_DeleteOnClose );
test->show();


2 commentaires

Cela semble fonctionner très bien. Merci. Mais quand je crée 4 nouveaux "tests" -Widgets, par exemple et les fermez à nouveau, la création d'un autre "test" -Widget ne coûtera pas plus de mémoire, mais l'application utilise toujours autant que la mémoire que lorsque les 4 "Test" -Widgets encore existerait. Est-ce normal?


@Berschi, il est possible que Qt ou votre système d'exploitation effectue une certaine optimisation de la mémoire. Si le cinquième widget que vous avez mentionné dans votre commentaire ne causait plus de mémoire à utiliser, je ne m'en avais pas trop. Une autre option, si vous êtes concerné, c'est trouver un outil comme Valgrind et exécuter votre programme à travers elle.