Partage
  • Partager sur Facebook
  • Partager sur Twitter

operateur << avec Visual Studio 2017

    19 mars 2018 à 13:06:33

    Salut tout le monde 

    j'ai un problème avec la surcharge de mon operateur<< sur visual studio car ce dernier détecte une erreur mais que n'arrive pas à résoudre 

    voici mon fichier .h:

    #include <utility>
    #include <string>
    #include <ostream>
    
    
    
    class X {
    
    private:
    	std::string m_mot;
    	int* m_ptr;
    
    public:
    	X(): m_mot{"mot Inconnue."},m_ptr{new int(0)}
    	{}
    	X(std::string mot, int ptr): m_mot{mot},m_ptr{new int(ptr)}
    	{}
    	X(X const & copie): m_mot{copie.m_mot},m_ptr{new int(*(copie.m_ptr))}
    	{}
    
    	X& operator=(X const & copie) {
    		
    		if (this != &copie) {
    			m_mot = copie.m_mot;
    			delete m_ptr;
    			m_ptr = new int(*(copie.m_ptr));
    
    		}
    		return *this;
    	}
    
    	X(X&& source): m_mot{std::move(source.m_mot)}, m_ptr{new int(*(std::exchange(source.m_ptr,nullptr)))}
    	{}
    
    	X& operator=(X&& source) {
    
    		if (this != &source)
    		{
    			m_mot = std::move(source.m_mot);
    			m_ptr = std::exchange(source.m_ptr, nullptr);
    
    		}
    		return *this;
    	}
    
    	void swap(X autre) {
    		std::swap(m_mot, autre.m_mot);
    		std::swap(m_ptr, autre.m_ptr);
    	}
    
    	void afficher(std::ostream flux) {
    		flux << "\n\nMot: " << m_mot << "\nValeur: " << *m_ptr << std::endl;
    	}
    	
    };
    
    std::ostream&  operator<<(std::ostream flux1, X const a) {
    
    	a.afficher(flux1);
    	return flux1;
    }
    

    désolé pour le pointeur nue car c'est juste pour me facilité à comprendre la semantique de mouvement :)

    Merci pour votre aide

    • Partager sur Facebook
    • Partager sur Twitter
      19 mars 2018 à 13:42:35

      Salut MoiMoi134,

      tu dois savoir une, pour utiliser la sémantique de mouvement, tu dois être sur que ton constructeur et opérateur de mouvement tous deux ne doivent pas renvoyer une ou des erreurs, voila pour quoi on utilise le mot clé " noexcept ":

      class X{
      
       // tu implémente les autres constructeur et ton destructeur 
        
       X(X const&& copie) noexcept;
       X& operator=(X const&& copie)noexcept;
      }

      prochainement évite d'utiliser un pointeur nue préfère plutôt utiliser un " unique_ptr " ce mieux et facile .

      -
      Edité par EL-jos 19 mars 2018 à 13:43:13

      • Partager sur Facebook
      • Partager sur Twitter

      Ton présent détermine ton futur et la connaissance te placera au dessus de ta génération .

        19 mars 2018 à 14:56:22

        Deedolith a écrit:

        Salut,

        Respecter la syntaxe des surcharges, ca aide:
        http://en.cppreference.com/w/cpp/language/operators


        toujours rien, je meme fais un copie/coller mais Visual stidio détecte toujours une erreur.

        j'ai essayé  de créer des ascenseurs pour  pour surcharger l'opérateur << mais sans succès :'(

        • Partager sur Facebook
        • Partager sur Twitter
          19 mars 2018 à 15:07:00

          ça coince :honte:
          • Partager sur Facebook
          • Partager sur Twitter

          Ton présent détermine ton futur et la connaissance te placera au dessus de ta génération .

            19 mars 2018 à 16:03:47

            Ton opérateur fais des copies.

            PS:
            La sémantique de mouvement sur une classe ayant une sémantique de valeur, je ne suis pas convaincu que ce soit utile.

            Et si tu veux mieux comprendre la sémantique de mouvement, cette implémentation très simplifiée de la fonction move() devrait t'y aider:

            class data
            {
            private:
                int* mPtr;
            public:
                data(): mPtr{new int}
                {
                }
                friend data move(data& in);
            }
            
            data move(data& in)
            {
                data out;
                delete out.mPtr;
            
                    // out pointe sur in
                out.mPtr = in.mPtr;
            
                   // in ne pointe plus sur rien
                in.mPtr = nullPtr
                return out;
            }




            -
            Edité par Deedolith 19 mars 2018 à 16:17:49

            • Partager sur Facebook
            • Partager sur Twitter
              19 mars 2018 à 17:04:43

              Deedolith a écrit:

              Ton opérateur fais des copies.

              PS:
              La sémantique de mouvement sur une classe ayant une sémantique de valeur, je ne suis pas convaincu que ce soit utile.

              Et si tu veux mieux comprendre la sémantique de mouvement, cette implémentation très simplifiée de la fonction move() devrait t'y aider:

              class data
              {
              private:
                  int* mPtr;
              public:
                  data(): mPtr{new int}
                  {
                  }
                  friend data move(data& in);
              }
              
              data move(data& in)
              {
                  data out;
                  delete out.mPtr;
              
                      // out pointe sur in
                  out.mPtr = in.mPtr;
              
                     // in ne pointe plus sur rien
                  in.mPtr = nullPtr
                  return out;
              }




              -
              Edité par Deedolith il y a 39 minutes

              Oui mais j'avais déjà essayer de passer par adresse mais sans succès, exemple:

              std::ostream& operator<<(std::ostream& flux, X const& a){
              
               a.afficher(flux); // sachant que j'avais définie une méthode afficher(std::ostream& flux) dans ma classe X
              
              retrun flux;
              }

              pour ton exemple, en examinant, j'ai remarqué que cela fait la meme chose que la fonction std::exchange (C++11) que j'ai utilisé dans mon code  


              • Partager sur Facebook
              • Partager sur Twitter
                19 mars 2018 à 19:45:12

                MoiMoi134 a écrit:

                Salut tout le monde 

                j'ai un problème avec la surcharge de mon operateur<< sur visual studio car ce dernier détecte une erreur mais que n'arrive pas à résoudre 

                "Détecte une erreur"

                Et c'est quoi, cette erreur ? compilateur ? crash ? Elle dit quoi cette erreur ?

                • Partager sur Facebook
                • Partager sur Twitter
                  20 mars 2018 à 11:29:25

                  Merci à tous pour vos réponses,

                  j'ai résolue le problème car il était au niveau de fichier .o donc il fallait le supprimer puis faire une ré-compilation, alors maintenant ça marche parfaitement bien.

                  mais juste une question:

                  comme faire un déplacement manuellement ou lieu de laisser la charge au compilateur, je m'explique :

                  je voudrai faire faire appelle à mon constructeur ou opérateur de déplacement , exemple :

                  X a("toto", 5), b;
                  b = a;
                  donc que a soit déplacer dans b sans laissé la tache au compilo 
                  • Partager sur Facebook
                  • Partager sur Twitter
                    20 mars 2018 à 14:22:44

                    MoiMoi134 a écrit:

                    Oui mais j'avais déjà essayer de passer par adresse mais sans succès, exemple:

                    std::ostream& operator<<(std::ostream& flux, X const& a)
                    {
                    
                     a.afficher(flux); // sachant que j'avais définie une méthode afficher(std::ostream& flux) dans ma classe X
                    
                    retrun flux;
                    }

                    pour ton exemple, en examinant, j'ai remarqué que cela fait la meme chose que la fonction std::exchange (C++11) que j'ai utilisé dans mon code  


                    Loupé, ce n'est pas du passage de paramètre par adresse, mais par référence. Et c'est la forme indiquée dans la documentation.
                    Donc soit bête, et applique la sans te poser de questions.

                    Ensuite ton code devrais plutôt ressembler à ceci:

                    std::ostream& operator<<(std::ostream& flux, X const& a){
                    
                        flux << a.m_mot << *(a.m_ptr);  // affiche le mot et la valeur pointée
                        retrun flux;
                    }

                    Une fonction membre "afficher" au sein de la classe viole le SRP, c'est rarement de la responsabilité de la classe de s'afficher elle-même, elle a d'autres chats à fouetter.

                    MoiMoi134 a écrit:

                    je voudrai faire faire appelle à mon constructeur ou opérateur de déplacement , exemple :

                    X a("toto", 5), b;
                    b = a;

                    donc que a soit déplacer dans b sans laissé la tache au compilo 

                    Tout simplement:
                    X a("toto", 5)
                    X b = std::move(a);
                    Mais garde bien en tête que le contenu de l'objet déplacé est invalidé. Continuer à l'utiliser est un comportement indéterminé.
                    • Partager sur Facebook
                    • Partager sur Twitter
                      20 mars 2018 à 14:59:59

                      Deedolith, merci beaucoup pour ton éclaircissement  mais j'avais trouvé une astuce donc c'est de déclarer operator<< comme ami à la classe^^  avoue que géniale comme idée.

                      mais encore une autre question par-apport à ta portion de code, tel que:

                      X a("toto", 5)
                      X b = std::move(a);

                      donc si tu me recommande d'utiliser directement std::move() dans mon main donc cela ne sert à rien de créer un constructeur et un opérateur par de mouvement ?

                        je me tape trop les doigts pour créer un constructeur et un opérateur par mouvement :-°

                      • Partager sur Facebook
                      • Partager sur Twitter
                        20 mars 2018 à 15:04:55

                        tu peux utiliser une méthode plus rapide pour le faire :

                        class X{
                        
                          X(X&& source) = default;
                          X& operator=(X&& source) = default;
                        }
                        mais sauf que avec cette méthode c'est le compilateur qui gère tout 
                        • Partager sur Facebook
                        • Partager sur Twitter

                        Ton présent détermine ton futur et la connaissance te placera au dessus de ta génération .

                          20 mars 2018 à 15:14:41

                          MoiMoi134 a écrit:

                          Deedolith, merci beaucoup pour ton éclaircissement  mais j'avais trouvé une astuce donc c'est de déclarer operator<< comme ami à la classe^^  avoue que géniale comme idée.

                          C'est exactement ce qui est écrit dans la doc (l'as-tu lue ?)

                          The overloads of operator>> and operator<< that take a std::istream& or std::ostream& as the left hand argument are known as insertion and extraction operators. Since they take the user-defined type as the right argument (b in a@b), they must be implemented as non-members.

                          MoiMoi134 a écrit:

                          mais encore une autre question par-apport à ta portion de code, tel que:

                          X a("toto", 5)
                          X b = std::move(a);

                          donc si tu me recommande d'utiliser directement std::move() dans mon main donc cela ne sert à rien de créer un constructeur et un opérateur par de mouvement ?

                            je me tape trop les doigts pour créer un constructeur et un opérateur par mouvement :-°

                          Dans ton cas particulier, a cause du pointeur nu, tu dois en implémenter un.

                          • Partager sur Facebook
                          • Partager sur Twitter
                            20 mars 2018 à 15:23:35

                            ah d'accord merci beaucoup pour votre aide, Deedolith et EL-jos ,

                            encore Merci :D

                            • Partager sur Facebook
                            • Partager sur Twitter

                            operateur << avec Visual Studio 2017

                            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                            • Editeur
                            • Markdown