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 :

Constructeur de copie sans "const"


Sujet :

C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Septembre 2004
    Messages : 30
    Par défaut Constructeur de copie sans "const"
    Bonjour

    En testant certains points des constructeurs de copie je suis tombé sur un petit mystère:

    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
    class A {
      int value;
    public:
      A(int i) { 
        value = i; 
        cout << "A(int)" << endl; 
      }
      A(A& other) {  // const volontairement absent
       value = other.value;
       cout << "A(A&)" << endl; 
      }
    };
     
    A a1(1), a2(a1); // ok
    A a3(*(new A(3))); // ok
    A a4(A(4)); // ne compile pas
    J'ai compilé en -fno-elide-constructors sous g++ 3.3.3 pour être bien sûr de voir passer toutes les copies avant que le compilateur ne s'amuse à les optimiser.

    Le message d'erreur est:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    error: no matching function for call to 'A::A(A)'
    error: candidates are: A::A(int)
    error:                 A::A(A&)
    Si je modifie le constructeur de copie en A(const A& other) le code compile et produit bien le résultat attendu (A(int), A(const A&) et a4.value = 4 au final).

    Je suis perplexe... Quelqu'un peut expliquer pourquoi?

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Les fonctiosn acceptant une référence non-const n'acceptent pas un temporaire non-nommé.

    Je crois que pour éviter ce genre de problème, les std::auto_ptr<>, dont le constructeur de copie est non-const, passent par une variable intermédiaire...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Parce qu'un temporaire n'est pas convertible vers une référence mais uniquement vers une référence vers const.

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Septembre 2004
    Messages : 30
    Par défaut
    Citation Envoyé par loufoque
    Parce qu'un temporaire n'est pas convertible vers une référence mais uniquement vers une référence vers const.
    Ok. Mais dans ce cas le message d'erreur est vraiment bizarre...

    Est-ce que ça veut dire que le compilo, ne pouvant pas convertir A(4) en A&, essaye de prendre le paramètre du constructeur simplement par valeur et qu'il rale parce qu'il n'existe pas (et ne peut pas exister un A(A foo)) ?

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Septembre 2004
    Messages : 30
    Par défaut
    Citation Envoyé par Médinoc
    Les fonctiosn acceptant une référence non-const n'acceptent pas un temporaire non-nommé.
    Je ne crois pas, car A(*(new A(4))) induit une référence non nommée non plus mais passe sans problèmes...

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Le temporaire non-nommé n'est plus ici l'objet, mais le pointeur.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Est-ce que ça veut dire que le compilo, ne pouvant pas convertir A(4) en A&, essaye de prendre le paramètre du constructeur simplement par valeur et qu'il rale parce qu'il n'existe pas (et ne peut pas exister un A(A foo)) ?
    Oui, enfin le compilateur cherche de toutes façons par valeur d'abord.

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