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

C++ Discussion :

SWAP IDIOM COPY CONSTRUCTOR


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    688
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 688
    Par défaut SWAP IDIOM COPY CONSTRUCTOR
    salut,

    pourquoi implémenter le constructeur de copie en utilisant la méthode swap ? versus une simple affectation ?

    Merci.

  2. #2
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    Bonjour,
    Ça n'existe pas le "SWAP IDIOM COPY CONSTRUCTOR".
    L'idiome copy and swap est utilisé pour l'opérateur d'affectation pas pour le constructeur de copie.

  3. #3
    Membre très actif
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    688
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 688
    Par défaut
    bon bon soit
    mais pourquoi ?

  4. #4
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par guillaume07 Voir le message
    bon bon soit
    mais pourquoi ?
    Pourquoi quoi ?

    Pourquoi on n'utilise pas l'idiome copy and swap pour le constructeur de copie ?

    Parce que ça ne sert à rien. En cas d'exception, l'objet n'est tout simplement pas construit, il n'y a donc pas de précaution particulière à prendre pour conserver l'objet (qui n'existera pas) dans l'état initial ou dans un état cohérent.
    En outre, que veux tu échanger puisque l'objet n'a pas d'existence (on est en train de le construire).

  5. #5
    Membre très actif
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    688
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 688
    Par défaut
    ok je reformule
    pourquoi utilise t-on swap plutôt qu'une bête affectation.
    je peux le formuler également comme ceci :

    pourquoi

    tmp=a
    a=b
    b=tmp

    plutot que
    a=b

  6. #6
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    pourquoi utilise t-on swap plutôt qu'une bête affectation.

    Mais justement on ne le fait pas !
    Il n'y a pas besoin de swap dans un constructeur par copie. Comme l'a dit gl l'objet n'est même pas encore construit, avec quoi ferait-on des échanges ?

  7. #7
    Membre très actif
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    688
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 688
    Par défaut
    oui pourquoi swaper dans l'operateur d'affectation

  8. #8
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    Parce que avec le copy & swap il est beaucoup, *beaucoup* plus simple de coder un opérateur d'affectation correct (et en particulier qui donne de bonnes garanties face aux exceptions).

    Mais attention :

    1) Dans l'idiome copy-and-swap on n'utilise jamais le swap bête par défaut. Il faut rajouter à la classe une fonction swap un peu plus intelligente qui va swapper les parties internes à la classe.
    2) il ne faut pas employer le copy-and-swap à tout bout de champ, en fait son utilisation est même plutôt rare. On n'utilise *pas* le copy-and-swap dans les cas suivants
    • Si la classe n'est pas copiable. Ça peut paraître évident, mais perso vu que la plupart de mes classes sont des entités je désactive presque tout le temps la copie.
    • Si la classe ne contient comme données membres que des types de base (int, float, double...). Pas besoin de coder l'op=, celui généré par défaut suffit.
    • Si la classe ne contient comme données membres que des types qui savent se copier eux-même (c.a.d dont le copy ctor et l'op= est définit, comme par exemple std::string, std::map, std::shared_ptr...). Pas besoin non plus de coder l'op=, celui généré par défaut est là aussi suffisant


    Finalement le copy-and-swap n'est généralement utile que si la classe est copiable, qu'elle possède des pointeurs nus sur des ressources, et que pour X raisons on ne peut pas encapsuler ces pointeurs nus dans des smarts pointeurs.

    Donc c'est pas souvent mais quand on se retrouve dans ce cas le copy-and-swap est une bénédiction. Par exemple, je reprends l'exemple donné dans cet article éclairant. On a une classe TFoo toute bête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    class TFoo : public TSuperFoo {
        TBar* fBar1;
        TBar* fBar2;
        // various method definitions go here...
    }
    Si l'on ne peut pas encapsuler les deux pointeurs dans des shared_ptr et si l'on ne veut pas utiliser le copy-and-swap, alors coder un op= correct pour cette classe tourne vite au cauchemar. L'article détaille un par un tous les pièges à éviter et fini par obtenir l'horreur (correcte!) suivante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    TFoo&
    TFoo::operator=(const TFoo& that)
    {
        if (this != &that) {
            TBar* bar1 = 0;
            TBar* bar2 = 0;
     
            try {
                bar1 = new TBar(*that.fBar1);
                bar2 = new TBar(*that.fBar2);
            }
            catch (...) {
                delete bar1;
                delete bar2;
                throw;
            }
     
            TSuperFoo::operator=(that);
            delete fBar1;
            fBar1 = bar1;
            delete fBar2;
            fBar2 = bar2;
        }
        return *this;
    }
    Ça m'étonnerais que beaucoup de programmeurs C++ arrivent à coder un op= comme celui-ci du premier coup ! Il faut une concentration extraordinaire. Alors qu'avec un petit coup d'idiome copy-and-swap, il suffit de définir une fonction swap très simple qui échange les deux pointeurs bar1 et bar2 et l'opérateur = devient simplissime à coder tout en étant correct même en cas d'exception :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    void TFoo::swap(const TFoo& that)
    {
       TSuperFoo::swap(that);
       std::swap(fBar1, that.fBar1);
       std::swap(fBar2, that.fBar2);
    }
     
    TFoo& TFoo::operator=(const TFoo& that)
    {
      TFoo tmp(that);
      this->swap(tmp);
      return *this;
    }
    Donc au final je dirais que le principal intérêt du copy-and-swap c'est d'économiser du temps de cerveau disponible.

Discussions similaires

  1. probleme avec copy constructor
    Par alamata dans le forum C++
    Réponses: 15
    Dernier message: 06/11/2014, 08h34
  2. vector et copy constructor
    Par r0d dans le forum Langage
    Réponses: 5
    Dernier message: 27/12/2012, 19h49
  3. copy constructor/ assignement/ destructor
    Par lafrankette dans le forum Débuter
    Réponses: 5
    Dernier message: 24/08/2009, 18h09
  4. [debutant]probleme avec le copy constructor
    Par Battosaiii dans le forum Débuter
    Réponses: 10
    Dernier message: 09/11/2005, 10h33
  5. Copy constructor ?
    Par Keyser dans le forum MFC
    Réponses: 4
    Dernier message: 17/02/2004, 15h33

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