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 :

Un objet construit sans appel à un constructeur ?


Sujet :

C++

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2014
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 142
    Points : 109
    Points
    109
    Par défaut Un objet construit sans appel à un constructeur ?
    Bonjour, j'ai écrit ce code pour comprendre comment se passe les différentes constructions (default/copie/move) :
    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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
     
    int osef(int); //fonction onsenfout (randomlike)
    void print(const string & m=""){cout<<m<<endl;} //print quoi
     
    class MyInt{ 
    private:
      int val; 
      string c; // Pour le nom de la variable dans le main et suivre les différentes étapes lors de passages/retour par fonctions.
      void print(const string& Opt="") const { // Fonction d'affichage lors des constructions et operations d'assign
      ostringstream out;
      out<< Opt <<" ("<<c<<" = "<<val<<")";
      ::print(out.str());
    }
     
    public:
      MyInt() : val{0}, c{"d"} {
        print("Constr Defaut");  //Aff
      }
     
      MyInt(const int& i, const string& e) : val{i}, c{e} {
        print("Constr Init"); //Aff
      }
     
      MyInt(const MyInt& I) : val{I.val}, c{I.c} {
        c+="(copy)";
        print("Constr Copy"); //Aff
      }
     
      MyInt(MyInt&& I) : val{I.val}, c{I.c} {
        c+="(cmovedIN)";
        I.c+="(cmovedOUT)";
        I.val=::osef(I.val);
        print("Constr Move"); //Aff
      }
     
      MyInt& operator =(const MyInt& I) {
        c="E_"+I.c;
        val=I.val;
        print("Copy Assign"); //Aff
        return *this;
      }
     
      MyInt& operator =(MyInt&& I){
        val=I.val;
        c=I.c+"(emovedIN)";
        I.c+="(emovedOUT)";
        I.val=osef(osef(I.val));
        print("Move Assign"); //Aff
        return *this;
      }
     
      friend MyInt operator +(const MyInt& , const MyInt& );
     
      ~MyInt() {print("Destr");}
    };
    MyInt operator +(const MyInt& A, const MyInt& B)
    {
      MyInt res(A.val,"res("+A.c+"+"+B.c+")");
      res.val+=B.val;
      return res;
    }
    Associé a un main que je commente // avec la sortie console et /* ce a quoi je m'attends et/ou pourquoi ca me pose probleme */.
    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
     
    MyInt A(2,"A"); //  Constr Init (A = 2)
                           /*    OK    */
     
    MyInt B(4,"B"); // Console : Constr Init (B = 4)
                            /*     OK       */
     
    MyInt C = A + B;     // Constr Init (res(A+B) = 2)
                                  /*  En partie OK : Appel au constructeur de res dans MyInt::operator+, mais le problème c'est que c'est tout...
                                   *  je m'attendais à un appel de MyInt::MyInt(Myint&&) pour construire C 
                                   *  ainsi qu'a un appel du destructeur de la variable locale res dans MyInt::operator+ 
                                   *  */
     
    print("**** Fin *****"); //**** Fin ***** 
                                  /* ... */
                                  //Destr (res(A+B) = 6)
                                  /* Ok, détruit C */
    return 0;

  2. #2
    Membre expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    739
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

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

    Informations forums :
    Inscription : Juin 2011
    Messages : 739
    Points : 3 627
    Points
    3 627
    Par défaut
    Bonsoir,

    Ceci est un effet de la RVO.
    Il est possible de la désactiver dans gcc avec -fno-elide-constructors.
    Mais il y a aura 2 moves car cela désactive aussi la NRVO.

    Je dois être fatigué, je ne trouve pas d'exemple ou le move se fait implicitement.
    Par contre, tu peux essayer avec MyInt D = std::move(C);.

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2014
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 142
    Points : 109
    Points
    109
    Par défaut
    Ok, je viens d'insérer un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if(true==false) return MyInt(); //avant le 'vrai' return de MyInt::operator +
    Et j'ai bien ce a quoi je m'attendais (il n'y a qu'un move).
    Merci en tout cas, si j ai bien compris c est la NRVO qui était à l'oeuvre la vu que mon objet retourné était copié et pas construit dans l'instruction return elle meme.

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

Discussions similaires

  1. Instancier une classe sans appeler son constructeur ?
    Par Maitre2B dans le forum Débuter avec Java
    Réponses: 4
    Dernier message: 15/11/2014, 16h38
  2. Réponses: 1
    Dernier message: 26/08/2010, 10h09
  3. Réponses: 5
    Dernier message: 30/03/2010, 10h46
  4. Reflection : Créer une instance sans appeler le constructeur
    Par cboun94 dans le forum Framework .NET
    Réponses: 8
    Dernier message: 17/12/2007, 17h26
  5. Faire appel à un constructeur d'un objet
    Par ploxien dans le forum Langage
    Réponses: 8
    Dernier message: 03/05/2007, 10h32

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