Partage
  • Partager sur Facebook
  • Partager sur Twitter

[TP ZString] probleme

...plutot incompréhensible...

    8 juin 2008 à 12:23:41

    Bonjour !
    Je suis en train d'essayer de coder la classe ZString, du tuto de Mateo21, et ... j'en arrive la ou il faut surcharger l'operator= (qui recoit une tableau de char) et... je le code, mais lors du test, ca ne marche pas . je vous explique, quand je compile il n'y a pas de probleme, mais lorsque j'affecte un tableau de char a ma chaine(Zstring), et lorsque je veux voir la nouvelle chaine de ma ZString, ca m'affiche des caracteres... vraiment bizarres ! (du genre une mini-roue ( ??^^), un ë , enfin bref tout plein de caractere qui n'ont rien a faire ici ^^. La longueur de la chaine est bonne (quand je tape machaine = "salut"; ==> il reconnait que la chaine fait 5 caracteres, mais il ne l'affiche pas correctement) ...

    Bref je vous post mon code ... Merci d'avance !
    Main.cpp
    #include <iostream>
    #include "ZString.h"
    using namespace std;
    
    int main()
    {
        cout << "Hello world!" << endl;
        ZString chaine("Bonjour!");
        chaine.display();
    
        chaine = "Salut";
        chaine.display();
        return 0;
    }
    


    ZString.cpp
    #include <iostream>
    #include "zstring.h"
    
    using namespace std;
    
    ZString::ZString() : m_char(NULL),m_length(0)
    {
    }
    ZString::ZString(const char* txt)
    {
        m_length = lengthf(txt);
        m_char = copy(txt);
    }
    ZString::ZString(ZString & zstring)
    {
        m_char = zstring.m_char;
        m_length = zstring.m_length;
    }
    ZString::~ZString()
    {
        delete[] m_char;
    }
    
    
    int ZString::lengthf(const char *txt)
    {
        int i=0;
        while (txt[i] != '\0')
        {
            i++;
        }
        return i;
    }
    char* ZString::copy(const char *txt)
    {
        int length = lengthf(txt);
        char * tableau = new char[length+1];
    
        for(int i = 0; i < length; i++)
        {
            tableau[i] = txt[i];
        }
        tableau[length] = '\0';
        return tableau;
    }
    void ZString::display()
    {
        cout << m_char << endl << "Cette chaine est de longueur " << m_length << endl;
    }
    
    ZString ZString::operator=(const char* txt)
    {
        delete[] m_char;
        m_char = copy(txt);
        m_length = lengthf(txt);
        return *this;
    }
    

    ZString.h
    #ifndef ZSTRING_H_INCLUDED
    #define ZSTRING_H_INCLUDED
    
    class ZString
    {
        public:
        ZString();
        ZString(const char* txt);
        ZString(ZString & zstring);
        ~ZString();
    
        int lengthf(const char *txt);
        char* copy(const char *txt);
        void display();
    
        ZString operator=(const char* txt);
        private:
        char * m_char;
        int m_length;
    };
    
    
    #endif // ZSTRING_H_INCLUDED
    


    Ps: j'utilise Code::blocks.
    • Partager sur Facebook
    • Partager sur Twitter
      8 juin 2008 à 20:06:10

      Plusieurs choses mènent à cette erreur :
      - Ton opérateur = renvoie par valeur, donc tu renvoies à chaque fois une copie alors qu'il faudrait simplement renvoyer une référence sur l'objet
      - Ton constructeur par copie (qui au passage devrait prendre son paramètre par référence constante) ne fait pas de copie du tableau mais seulement du pointeur, càd que deux chaînes copiées vont pointer sur le même tableau de caractère. Or dès la destruction de l'une d'entre elles, le tableau sera détruit par le destructeur et la seconde pointera alors vers un tableau invalide car détruit.

      Je ne te donne pas de réponse plus précise, je te laisse réfléchir à comment tu pourrais corriger cela ;)
      • Partager sur Facebook
      • Partager sur Twitter
        8 juin 2008 à 22:12:02

        Mmmhhh...

        Citation : Mateo

        Le return *this, je ne reviens pas dessus, c'est comme ça que tout operator= doit terminer, point barre


        moi cela me parait logique ... on renvoie l'objet lui meme affecté d'une nouvelle valeur ...
        EDIT : Ahhh :) J'ai cherché un peu plus de documentation sur developpez.com, et j'ai vu comment ils renvoyaient une reference pour l'affection ... :) et ca marche !! :):) (mais ne comprend pas vraiment pourquoi avec *this , cela ne marche pas ... :euh: embetant !)

        Et pour le constructeur, j'ai eu du mal a voir au debut mais effectivement, tu as raison ...! Je met mes changements, dites moi si c'est bon :)
        l'affectation :
        ZString& ZString::operator=(const char* txt)
        {
            delete[] m_char;
            m_char = copy(txt);
            m_length = lengthf(txt);
            return *this;
        }
        

        Le constructeur par copie :
        ZString::ZString(const ZString &pzstring)
        {
            m_char = copy(pzstring.m_char)
            m_length = pzstring.m_length;
        }
        


        Merci encore !
        • Partager sur Facebook
        • Partager sur Twitter
          8 juin 2008 à 22:21:11

          C'est tout bon, bien joué ;)
          • Partager sur Facebook
          • Partager sur Twitter
            8 juin 2008 à 22:45:34

            Presque. Toujours dupliquer avant d'effacer.
            (avec un swap, c'est très simple à faire)
            • Partager sur Facebook
            • Partager sur Twitter
            C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
              8 juin 2008 à 22:57:55

              Euh ... et pouvez vous m'expliquer ce qu'est un swap alors :D ?

              EDIT : j'ai repondu un peu tp vite excusez moi ^^
              ok, je vais faire ca , mais quel est l'interet ... ?
              PS: Quelqu'un peut m'expliquer pourquoi mon code ne marchait pas tout à l'heure quand je renvoyais juste *this ? j'aimerais bien comprendre :D
              • Partager sur Facebook
              • Partager sur Twitter
                9 juin 2008 à 9:18:43

                Doucement avec le swap, faut pas trop brusquer les débutants :lol:

                Citation : Pas de titre

                Quelqu'un peut m'expliquer pourquoi mon code ne marchait pas tout à l'heure quand je renvoyais juste *this ?


                Tu renvoies toujours *this, simplement tu ne le renvoies pas de la même manière. Avant tu en renvoyais une copie, et comme ton constructeur par copie était buggé tu étais en plein dans l'erreur. Maintenant tu renvoies une référence vers *this, donc aucune copie n'est faite.
                • Partager sur Facebook
                • Partager sur Twitter
                  9 juin 2008 à 9:21:02

                  L'important n'est pas de renvoyer *this, mais sous quelle type *this est renvoyé.

                  Si tu renvois *this comme un "ZString", il va falloir faire une copie pour créer un nouveau ZString. Ceci posse évidemment problème si tu réalises une copie dans le constructeur de copie. L'ordinateur ne sait pas comment gérer cela sans partir dans une boucle infinie.

                  L'idée de lmghs est de créer une nouvelle fonction membre qui ferait l'échange entre 2 ZString. Tu pourrais alors coder la copie comme une duplication suivie d'une destruction et pas le contraire. Comme tu l'as fait, si le delete[] merde (rare mais possible), tu perds toute l'information alors que si tu fais le contraire, la copie n'aura peut-être pas lieu mais au moins les données ne sont pas perdues.
                  • Partager sur Facebook
                  • Partager sur Twitter
                  Co-auteur du cours de C++. ||| Posez vos questions sur le forum ||| Me contacter.
                    9 juin 2008 à 10:47:30

                    <hs>

                    Citation : Laurent Gomila

                    Doucement avec le swap, faut pas trop brusquer les débutants :lol:


                    Ce n'est pas plus compliqué que les pointeurs.
                    Et quitte à leur montrer les pointeurs, autant leur montrer dessuite les bonnes recettes d'utilisation. AMA, c'est toujours mieux que d'entendre 5 ans plus tard: "ton truc c'est mauvais.", "Mais! C'est comme ça que j'ai appris!", "Ben ... désapprends, et apprends ça à la place".
                    </hs>
                    • Partager sur Facebook
                    • Partager sur Twitter
                    C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
                      9 juin 2008 à 23:13:30

                      Mmhhh... Je "crois" avoir compris ...^^ bref je verrais avec la pratique de toute facon et pis je vais googliser un peu tout ca pour que ca m'eclaire l'esprit :)

                      Merci encore a vous tous !
                      • Partager sur Facebook
                      • Partager sur Twitter

                      [TP ZString] probleme

                      × 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