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 par copie


Sujet :

C++

  1. #1
    Membre du Club
    Inscrit en
    Janvier 2010
    Messages
    153
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 153
    Points : 59
    Points
    59
    Par défaut Constructeur par copie
    Bonjour,
    Je suis en train de tester le comportement du constructeur par copie sous C++

    Voici le code template
    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
     
    #include <iostream>
    using namespace std;
     
    class A{
    public:
    	int i;
    	A(int i) : i( i ){ cout << "Constructor" << endl;};
    	~A(){ cout << "Destructor" << endl;};
    	A(const A& a)
    	{ 
    		cout << "Constructor copy" << endl; 
    		i = a.i;
     
    	};
    	A& operator=(const A& a){cout <<"Operator=" << endl;};
    };
     
    A foo()
    {
    	cout << "inside foo" << endl;
    	A a( 1 );
    	return a;
     
    };
     
     
    int main()
    {
    	A b( foo() );
    	//A a( b );
     
    	cout << " b.i " << b.i << endl;
    	system("pause");
    	return 0;
    }
    Le comportement est normal, si je fais Le output est affiché normalement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    inside foo
    Constructor
    Constructor copy
    Destructor
     b.i 1
    Press any key to continue . . .
    Par contre si je modifie la méthode foo()
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    A foo()
    {
    	cout << "inside foo" << endl;
    	return A( 1 );
     
    };
    Le output est comme ça

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    inside foo
    Constructor
     b.i 1
    Press any key to continue . . .
    La question est la copie se fait par quelle méthode? D'après le output, les valeurs de b sont bien initialisés mais je ne vois pas quelle méthode a été utilisées?

    Merci

  2. #2
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

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

    Je pense que le compilateur fais une optimisation dans le 2eme cas. Quel compilateur utilises-tu? Quelles options d'optimisation?
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  3. #3
    Membre du Club
    Inscrit en
    Janvier 2010
    Messages
    153
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 153
    Points : 59
    Points
    59
    Par défaut
    Citation Envoyé par r0d Voir le message
    Bonjour,

    Je pense que le compilateur fais une optimisation dans le 2eme cas. Quel compilateur utilises-tu? Quelles options d'optimisation?
    J'utilise Visual Studio 2010

  4. #4
    Inactif  


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

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Je pense que c'est une "Return Value Optimization" (à confirmer par les experts C++ du forum).

    Par contre j'aurais pensé que la première version aurait été optimisé aussi (par "Named Return Value Optimization").
    De plus, je me serais attendu à ce que le constructeur soit appelé en premier avant foo() après optimisation. Il faut que je revois ça.

    EDIT : après vérification ici, on a bien une NRVO dans le premier cas (on gagne en fait un appel au constructeur de copie).
    Par contre, je ne comprend toujours pas pourquoi on a l'appel au constructeur après l'appel à la fonction foo()

  5. #5
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    Citation Envoyé par gbdivers Voir le message
    Par contre j'aurais pensé que la première version aurait été optimisé aussi (par "Named Return Value Optimization").
    La première version est optimisé avec vs2010, mais hibou107 a testé uniquement en debug et pas en release.
    Visual studio n'applique pas la NRVO en debug, il applique seulement la URVO (unamed value optimization, c'est à dire le retour d'un temporaire anonyme, comme dans le second cas).
    http://connect.microsoft.com/VisualS...-in-debug-mode

  6. #6
    Membre chevronné Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 043
    Points : 2 234
    Points
    2 234
    Par défaut
    C'est simplement une optimisation des compilateurs, ça ne pourrait être le cas avec une classe plus complexe. Ici, la classe ne contient que un int donc facile à optimiser, la NRVO n'y est pour rien dans ce cas. Avec une structure plus complexe je doute que le compilateur puisse déduire une telle optimisation sans la NRVO.

    Si le constructeur est appelé après c'est parce que elle semble "inliner".
    si le compilateur rencontre un code du type:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    {
      A a;
      return a;
    }
    A b(a);
    il peut facilement l'optimiser en
    Mais a ta place je porterais une attention particulière dans le cas ou A détient une allocation dynamique.
    LA NRVO est a surveiller de prêt au moment de la release a ce moment la...
    Homer J. Simpson


  7. #7
    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
    Points : 13 017
    Points
    13 017
    Par défaut
    Bonjour,
    F.A.Q. : Qu'est-ce que la RVO ? et les suivantes

Discussions similaires

  1. [POO] Constructeur par copie
    Par kacedda dans le forum C++
    Réponses: 16
    Dernier message: 05/05/2007, 12h38
  2. [Debutant] Problème avec un constructeur par copie
    Par Drannor dans le forum Débuter
    Réponses: 5
    Dernier message: 12/03/2007, 09h15
  3. Réponses: 5
    Dernier message: 03/12/2006, 15h55
  4. Constructeur par copie et std::list
    Par Captain_JS dans le forum SL & STL
    Réponses: 5
    Dernier message: 13/12/2005, 19h15
  5. [deb.]Constructeur par copie
    Par Marc_3 dans le forum Débuter
    Réponses: 4
    Dernier message: 19/11/2005, 13h33

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