IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SL & STL C++ Discussion :

Que mettre dans un std::vector : objet, pointeur, référence


Sujet :

SL & STL C++

  1. #1
    Membre habitué

    Femme Profil pro
    Développeur informatique
    Inscrit en
    Février 2004
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 59
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2004
    Messages : 58
    Points : 166
    Points
    166
    Par défaut Que mettre dans un std::vector : objet, pointeur, référence
    Bonjour,

    J'avais un std::vector<A>, mais maintenant, mes A peuvent aussi être des A1 (classe dérivée).
    Suis-je donc obligée de transformer mon std::vector<A> en std::vector<A*>
    (et donc de gérer les pointeur ) ou existe-t'il un autre moyen en utilisant des références ?

    Merci d'avance.

  2. #2
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    On ne peut pas stocker des références dans un conteneur, celles-ci n'étant pas des "objets" mais simplement des alias pour d'autres variables.

    La meilleure solution pour ne pas s'occuper de la gestion de la mémoire est de stocker des pointeurs intelligents avec comptage de référence ; boost::shared_ptr ou Loki::SmartPtr par exemple.

  3. #3
    Membre habitué

    Femme Profil pro
    Développeur informatique
    Inscrit en
    Février 2004
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 59
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2004
    Messages : 58
    Points : 166
    Points
    166
    Par défaut
    Merci bien pour ta réponse !
    Anne.

  4. #4
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par Loulou24
    On ne peut pas stocker des références dans un conteneur, celles-ci n'étant pas des "objets" mais simplement des alias pour d'autres variables.

    La meilleure solution pour ne pas s'occuper de la gestion de la mémoire est de stocker des pointeurs intelligents avec comptage de référence ; boost::shared_ptr ou Loki::SmartPtr par exemple.
    Le problème est qu'alors les objets ont une sémentique de pointeur. Dans certains cas, on peut vouloir garder une sémentique par valeur. Dans ce cas, un petit pointeur intelligent fait main avec deep copy peut faire l'affaire. genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    template <class T> class ValuePtr
    &#123;
       T* myPtr;
       ValuePtr&#40;T* t&#41; &#58; myPtr&#40;t&#41; &#123;&#125;
       ~ValuePtr&#40;&#41; &#123;delete myPtr;&#125;
       ValuePtr&#40;ValuePtr const &vptr&#41; &#58; myPtr&#40;vptr->clone&#40;&#41;;&#41;;
       void swap&#40;ValuePtr &vptr&#41; &#123;std&#58;&#58;swap&#40;myPtr, vptr.myPtr&#41;;&#125;
       ValuePtr operator=&#40;ValuePtr const &vptr&#41; &#123;ValuePtr temp&#40;vptr&#41;; 
          temp.swap&#40;this&#41;; &#125;
       T* operator->&#40;&#41;&#123;return myPtr;&#125;
       T const * operator->&#40;&#41; const &#123;return myPtr;&#125;
    &#125;;
    Où clone implémente l'idiome du constructeur virtuel.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  5. #5
    Membre habitué

    Femme Profil pro
    Développeur informatique
    Inscrit en
    Février 2004
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 59
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2004
    Messages : 58
    Points : 166
    Points
    166
    Par défaut
    Je vois le principe, mais je ne comprend pas tout...
    C'est quoi swap ?
    Et puis : il manque le destructeur pour détruire le pointeur, non ?

  6. #6
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par _Anne_
    Je vois le principe, mais je ne comprend pas tout...
    C'est quoi swap ?
    C'est une fonction qui échange ses deux valeurs. Elle a la propriété qu'elle ne peut pas lancer d'exception, et donc elle est très utile pour écrire du code exception-safe : Au lieu de modifier directement un objet (par exemple, dans operator=), ce qui peut être gênant si la n-ième modification échoue (comment revenir à l'état initial), on modifie un objet temporaire, puis on échange les deux objets par une fonction dont on sait qu'elle ne pourra pas échouer.

    Citation Envoyé par _Anne_
    Et puis : il manque le destructeur pour détruire le pointeur, non ?
    Oui, effectivement, un ch'tit oubli... Je vais éditer le message précédent pour l'ajouter.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  7. #7
    Membre habitué

    Femme Profil pro
    Développeur informatique
    Inscrit en
    Février 2004
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 59
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2004
    Messages : 58
    Points : 166
    Points
    166
    Par défaut
    Citation Envoyé par JolyLoic
    Citation Envoyé par _Anne_
    C'est quoi swap ?
    C'est une fonction qui échange ses deux valeurs. Elle a la propriété qu'elle ne peut pas lancer d'exception, et donc elle est très utile pour écrire du code exception-safe : Au lieu de modifier directement un objet (par exemple, dans operator=), ce qui peut être gênant si la n-ième modification échoue (comment revenir à l'état initial), on modifie un objet temporaire, puis on échange les deux objets par une fonction dont on sait qu'elle ne pourra pas échouer.
    Pardon, je dois être un peu bête , mais c'est quoi la différence entre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    FLDptrObj temp&#40;vptr&#41;;
    temp.swap&#40;this&#41;;
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    myPtr = vptr->clone&#40;&#41;;
    :

    Comme je viens du C, je ne maitrise pas complètement les exceptions... ça doit être ça le problème !

    Par ailleurs, est-ce que dans l'affectation (operator=) , il ne va pas y avoir un soucis de fuite de l'ancien pointeur de l'objet courant ?

    Quoiqu'il en soit, merci beaucoup pour ton aide

  8. #8
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par _Anne_
    Pardon, je dois être un peu bête , mais c'est quoi la différence entre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    FLDptrObj temp&#40;vptr&#41;;
    temp.swap&#40;this&#41;;
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    myPtr = vptr->clone&#40;&#41;;
    Déjà, le but de clone :

    Si tu as B, D1 et D2 qui dérivent de B, alors quand tu possède un pointeur sur B, tu ne peux pas vraiment utiliser le constructeur de copie :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    B* b1 = new D1;
    B* b2 = new XX &#40;b1&#41;; // Suivant le type dynamique de b1, XX devrait être égal à B, D1 ou D2
    Donc, pour ça, on défini dans B une fonction virtuelle clone, que l'on surcharge dans toutes les classes dérivées. Le code est toujours le même :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    B* XX&#58;&#58;clone&#40;&#41; &#123;return new XX&#40;this&#41;;&#125;
    Donc clone permet d'avoir un constructeur de copie virtuel.

    Maintenant, le truc avec swap :
    Le but est double : Déjà, implémenter l'operator= à l'aide du constructeur de copie pour factoriser le code, deuxièment avoir un operator= qui en cas de problème n'a pas modifié l'objet auquel on essaye d'affecter.

    swap permet d'échanger deux valeurs, sans lancer d'exceptions. On crée donc dans un premier temps un objet temporaire en copiant l'objet passé en paramètre (ce qui appèlera lone). Ensuite, on échange l'objet nouvellement crée avec l'objet courant, puis on laisse cet objet temporaire mourir.

    En l'occurence, comme la classe n'a qu'une seule donnée, on aurait pu écrire directement clone, mais la technique avec swap marche dans tous les cas, ce qui n'est pas le cas de l'affectation directe. En particulier, s'il y a plusieurs variables membres et que après la première affectation, une exception est lancée, on se retrouve avec un état incohérent. J'ai donc pris l'habitude d'écrire mes operator= avec swap.

    Et de toute façon, founir une fonction swap pour ce genre de classes est une bonne idée, car elle peut être utile à une personne qui écrira un classe contenant un ValuePtr et autre chose, et qui aura donc besoin de swap lui même.

    J'espère avoir été plus clair, mais il n'est pas aisé de résumer dans un forum quelque-chose qui aurait plus sa place dans des articles dédiée. Par exemple Sutter en parle dans ses GOTW (http://www.gotw.ca/gotw/008.htm ou http://www.gotw.ca/gotw/059.htm par exemple, )
    Citation Envoyé par _Anne_
    Par ailleurs, est-ce que dans l'affectation (operator=) , il ne va pas y avoir un soucis de fuite de l'ancien pointeur de l'objet courant ?
    Quand l'objet temp sera détruit, ce pointeur sera pris en compte dans le destructeur.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  9. #9
    Membre habitué

    Femme Profil pro
    Développeur informatique
    Inscrit en
    Février 2004
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 59
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2004
    Messages : 58
    Points : 166
    Points
    166
    Par défaut
    Citation Envoyé par JolyLoic
    Déjà, le but de clone :
    oui,ça, ça va, j'utilise souvent...
    Citation Envoyé par JolyLoic
    Maintenant, le truc avec swap :
    Ok. Je comprend. Ici, on aurait pu faire plus simple, mais c'est plus général avec swap...
    Citation Envoyé par JolyLoic
    J'espère avoir été plus clair,
    C'est parfait merci beaucoup pour cette longue explication
    Citation Envoyé par JolyLoic
    Citation Envoyé par _Anne_
    Par ailleurs, est-ce que dans l'affectation (operator=) , il ne va pas y avoir un soucis de fuite de l'ancien pointeur de l'objet courant ?
    Quand l'objet temp sera détruit, ce pointeur sera pris en compte dans le destructeur.
    ok j'avais pas saisi que le swap échange les deux ! super !

    Merci encore !!!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [OLAP] Que mettre dans une table d'agrégats ?
    Par marchand_de_sable dans le forum Approche théorique du décisionnel
    Réponses: 77
    Dernier message: 14/10/2016, 23h25
  2. Réponses: 6
    Dernier message: 04/08/2013, 21h56
  3. que mettre dans DeFAUKT CHARSET
    Par saluts92 dans le forum Requêtes
    Réponses: 9
    Dernier message: 23/01/2007, 15h13
  4. Que mettre dans un champ DATETIME pour certains cas?
    Par Jim_Nastiq dans le forum Requêtes
    Réponses: 5
    Dernier message: 04/07/2006, 11h22
  5. Libération de pointeurs dans un std::vector
    Par G dans le forum SL & STL
    Réponses: 17
    Dernier message: 06/04/2005, 23h37

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo