8
votes

Attester les pointeurs à Qlist

J'ai besoin d'insérer des pointeurs de classes (hérité de QOBJECT) dans une QListe. Je sais que la syntaxe suivante peut être utilisée:

.h fort> p> xxx pré>

.cpp strong> p> p> xxx pré>

puis mémoire libre: p> xxx pré>

ceci doit être valide et ne provoque aucune fuite de mémoire (autant que je sache). Cependant, j'ai besoin d'initialiser des objets avant de les ajouter à la collection. La pièce de code suivante peut-elle provoquer des erreurs telles que des fuites de mémoire ou des pointeurs suspendus (je vais utiliser la même manière pour supprimer les pointeurs comme ci-dessus)? P>

MyObject *obj;

for(i = 0; i < 5; i++)
{   
    obj = new MyObject();
    if(!obj.Init(i, map.values(i)))
    {
        // handle error
    }
    else
    {
        list.append(obj);
    }
}


1 commentaires

Juste une note: le si (liste.ISPEDY ()) lorsque l'utilisation de qdeleteall () est redondante, je l'omettais simplement.


4 Réponses :


0
votes

Utiliser Raii (l'allocation des ressources est l'initialisation). Initialisez directement l'objet dans le constructeur.

Le code ressemblerait à: xxx


5 commentaires

Et si les exceptions ne sont pas autorisées dans son environnement?


... Ensuite, un autre mécanisme doit être trouvé pour les erreurs de rapport. Cela pourrait être quelque chose comme une fonction "getlasterror" (peut-être le fil de fil). Mais pourquoi supposer des exceptions non autorisées? Il n'y a rien mentionné dans la question, alors je l'ai gardé simple.


Lancer une exception était en fait sous mon examen. En cas d'échec d'initialisation, je souhaite recevoir un message d'erreur de l'objet à des fins de débogage (en utilisant actuellement la méthode publique obj.geterror ()). Je sais qu'il est possible de signaler des erreurs avec des exceptions (par exemple, jetant une chaîne), mais je joue actuellement avec des valeurs de retour et des messages d'erreur (comme les bibliothèques QT) et je voudrais rester sur ce chemin. C'est la raison principale pour laquelle j'ai demandé si le dernier code est bien.


Et j'aimerais ajouter que dans certaines situations, j'ai besoin de fonctionnalités similaires sur des initialisations beaucoup plus complexes et, par conséquent, la mise en constructeur ne semble pas être très raisonnable.


"Autre mécanisme" .. Oui, c'est pourquoi j'ai soulevé la question. Puisque nous ne connaissons pas la motivation derrière le code montré, je n'entraînerais aucun autre concept et je ne voudrais que répondre à la question. Il y a 1000 façons d'initialiser un objet et 1000 raisons de savoir pourquoi choisir l'un des 1000 :)



5
votes

Si vous prenez soin de "obj" (l'instance allouée mais non initialisée) dans le cas "// Manipul Error", votre code est correct.


0 commentaires

0
votes

Vous pouvez utiliser Qscopedpoinger ..

du QT 4.6 Documentation, P>

La classe QScopedpointer stocke un pointeur sur un objet alloué de manière dynamique et la supprime lors de la destruction. La gestion manuelle des objets alloués manuellement est dure et que l'erreur est exposée aux erreurs, avec le résultat commun que le code fuit la mémoire et est difficile à maintenir. QScopedpointer est une petite classe d'utilité qui simplifie fortement celle-ci en attribuant une propriété de mémoire basée sur la pile aux allocations de tas, plus généralement appelée que l'acquisition de ressources est l'initialisation (Raii) str forte>. P> P> P> P> P> P> P> P> P> P> P> P> P> P> P> P> P> P> P> P> P> P> P> P> P> P> P> P> P> P> J'espère que cela aide .. p>

EDIT: P>

Par exemple, P>

Vous utiliserez, P>

QWidget *p = new QWidget();


4 commentaires

Donc, la boucle interne ressemble à ceci: qscopedpointer obj (nouveau myObject ()); Si (obj-> init (carte.values ​​(i)) {list.append (obj.take ());} ... Ajouter ça pour répondre à l'avantage.


désolé je ne pouvais pas comprendre votre exemple. Mais il suffit d'ajouter un exemple de base des Documents pour que les choses se clarifient. Je vais ajouter ceci avant avec l'espoir que les gens vont quand même le trouver dans les docs .. :)


Quelle partie de mon exemple essentiellement 3 lignes n'est pas claire? BTW, votre exemple mènera à un Segfault, car le PTR ScOPed possède toujours l'instance, c'est pourquoi j'ai utilisé .take ().


QScopedpointer est non-copieux et ne peut donc pas être ajouté à une QListe.



4
votes

Utilisez plutôt QsharedPoinger. xxx

à la mémoire libre que vous devez faire xxx

à ajouter à la liste xxx


0 commentaires