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 OR operator= ?


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de foolib
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    111
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Juillet 2008
    Messages : 111
    Par défaut constructeur de copie OR operator= ?
    Mon problème est simple, dans le code ci dessous, je ne comprends pas pourquoi à la ligne indiquée dans main, le constructeur de copie est appelé plutôt que la méthode 'operator=' de la classe ...
    1 - Le constructeur de copie est censé n'intervenir qu'en cas de d'initialisation d'un objet : alors pourquoi b est concidéré non initialisé ?
    ( il est déclaré à la ligne du dessus, donc un constructeur par defaut a déjà fait le boulo non ?)
    2 - Enfin, que faudrait il pour que la méthode operator= soit appelée à cet endroit plutôt que le constructeur de copie ?

    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    #include <iostream>
    using namespace std;
     
    class point
    { int x, y;
    public :
    point (int abs=0,int ord=0){ 
    	x=abs; 
    	y=ord;
    }
    point (const point &p){ 
    	x=p.x; 
    	y=p.y;
    }
    ~point(){}
    point operator=(const point &p);
    point symetrique();
    }
     
    point point::symetrique(){
    	point res;
    	res.x = -x;	res.y = -y;
    	return res;
    }
     
    point operator=(const point &p){
    	x=p.x; 
    	y=p.y;
    	return *this;
    }
     
    int main(){
     
    point a(1,3), b;
     
    b = a.symetrique();  // <------ICI
     
    return 0;
    }
    Merci d'avance

  2. #2
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Bonjour RipCode

    La ligne suivante est une simple déclaration sans initialisation :
    Essaie de "forcer" l'initialisation avec pour appeler le constructeur par défaut :

  3. #3
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    Et remplacer un code correct par un code faux ? T'as de drole de conseils gbdivers.
    (pour plus d'information sur pourquoi "point b();" est faux, google -> "C++ most vexing parse", c'est une erreur vicieuse et très courante)

    Sinon, RipCode, sous vs2005, ton code passe bien dans l'opérateur= comme prévu. Tu utilises quel compilateur ?

  4. #4
    zul
    zul est déconnecté
    Membre chevronné Avatar de zul
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    498
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 498
    Par défaut
    Sans certitude, mais je pense que le compilateur peut (doit) optimiser dans ce cas précis, il n'a aucune raison de construire un objet par défaut, puisque le premier traitement que tu fais sur cette objet, c'est de lui affecter le retour de a.symetrique() (et dans ce cas là, il est valide d'appeler le constructeur par copie).

  5. #5
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    Non, il ne peut pas optimiser ici, car :
    force l'appel du constructeur par défaut.

    Le comilateur optimise dans ce cas là :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Point b = a.symetrique();
    L'optimisation étant qu'il n'y a plus de point temporaire crée dans la fonction symetrique() car le compilateur construit directement dans le point b. On a donc que deux appels aux constructeurs par défaut dans tous le programme, un pour a et un pour b, alors que dans le programme original de RipCode on a :
    Ctor (pour a)
    Ctor (pour b)
    Ctor (pour le temporaire dans symetrique)
    Operator = (pour la copie)

    Edit : D'ailleurs il y a une petite erreur dans l'operateur=, il faut renvoyer un point&, pas un point.

  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
    Citation Envoyé par Arzar Voir le message
    Non, il ne peut pas optimiser ici, car :
    force l'appel du constructeur par défaut.
    Le code du constructeur par défaut est visible et trivial, le compilateur peut donc l'inliner, ce qui revient ici à le supprimer.

    PS: Pourquoi l'opérateur = de ce code retourne-t-il une copie?
    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
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 290
    Billets dans le blog
    2
    Par défaut
    Bonjour,

    chez moi (j'ai compilé et testé avec visual 2008 express ed.), il passe bien par l'opérateur =, même en release avec optimisations.
    Cela dit, il passe bien par l'opérateur par copie avant. C'est dans la fonction symetrique(), à la ligne:
    qu'il fait une copie du point*. Mais ensuite, il affecte bien b à ce que retourne symetrique() en utilisant l'opérateur =.


    * ce qui est normal. Pour éviter cela, il faut passer par une référence.

  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
    Ben non c'est pas normal, rod.
    Ce comportement là (un constructeur par copie à la ligne return res; puis une affectation avec l'opérateur =) est typique du mode debug sous VS.
    En release, la ligne b = a.symetrique() ne déclenche qu'un appel à l'opérateur = .

    (Mais le must reste Point b = a.symetrique(), comme dit plus haut, car il n'y a acune copie du tout)

  9. #9
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Merci Arzar
    C'est probablement une erreur que je dois faire régulièrement...

  10. #10
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par Arzar Voir le message
    Et remplacer un code correct par un code faux ? T'as de drole de conseils gbdivers.
    (pour plus d'information sur pourquoi "point b();" est faux, google -> "C++ most vexing parse", c'est une erreur vicieuse et très courante)
    Et renvoyer vers des recherches approximatives ? Tu as de drôle de conseil Arzar Alors qu'on a la réponse en français dans la F.A.Q. de développez.

Discussions similaires

  1. [résolu]les constructeurs de copie
    Par pouss dans le forum Langage
    Réponses: 9
    Dernier message: 28/06/2005, 10h57
  2. Réponses: 3
    Dernier message: 24/04/2005, 14h19
  3. [C++]Heritage et constructeur de copie
    Par matazz dans le forum C++
    Réponses: 2
    Dernier message: 25/03/2005, 12h31
  4. Constructeur de copie modifiant le paramètre ?
    Par Nicodemus dans le forum C++
    Réponses: 4
    Dernier message: 12/01/2005, 21h25
  5. Constructeur de copie et Template: Transtypage
    Par ikkyu_os dans le forum Langage
    Réponses: 9
    Dernier message: 26/12/2004, 22h29

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