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 :

Programme surcharge opérateurs


Sujet :

C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 26
    Par défaut Programme surcharge opérateurs
    Bonjour, j'ai un petit soucis dans mon programme suivant :

    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
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    #include <conio.h>
    #include <iostream>
     
    using namespace std;
     
    class chaine
    {
          private :
                  int longueur;
                  char *adr;
          public :
                 chaine();
                 chaine(char *texte);
                 void operator =(chaine &ch);
                 int operator ==(chaine ch);
                 chaine &operator +(chaine ch);
                 char &operator [](int i);
                 ~chaine();
                 void affiche();
    };
     
    chaine::chaine()      //constructeur1
    {
                          longueur=0;
                          adr = new char[1];
    }
     
    chaine::chaine(char *texte)     //constructeur2
    {
                        int i;
                        for(i=0; texte[i]!='\0'; i++);
                        longueur = i;
                        adr = new char[longueur+1];
                        for(i=0; i!=(longueur+1); i++) adr[i] = texte[i];
    }
     
     
    void chaine::operator =(chaine &ch)
    {
         delete adr;
         longueur = ch.longueur;
         adr = new char[ch.longueur+1];
         for(int i=0; i!=(longueur+1); i++) adr[i] = ch.adr[i];
    }
     
    int chaine::operator ==(chaine ch)
    {
        int i, res=1;
        for(i=0; (i!=(longueur+1))&&(res!=0); i++) if(adr[i]!=ch.adr[i]) res=0;
        return res;
    }
     
    chaine &chaine::operator +(chaine ch)
    {
           int i;
           static chaine res;
           res.longueur = longueur + ch.longueur;
           res.adr = new char[res.longueur+1];
           for(i=0; i!=longueur; i++) res.adr[i] = adr[i];
           for(i=0; i!=ch.longueur; i++) res.adr[i+longueur] = ch.adr[i];
           res.adr[res.longueur]='\0';
           return res;
    }
     
    char &chaine::operator [](int i)
    {
         static char res='\0';
         if(longueur!=0) res= *(adr+i);
         return res;
    }
     
    chaine::~chaine()
    {
                     delete adr;
    }
     
    void chaine::affiche()
    {
         int i;
         for(i=0; i!=longueur; i++) cout << adr[i];
    }
     
    int main()
    {
         chaine a("Bonjour "),b("Maria"),c,d("Bonjour "),e;
     
         if(a==b) cout << "Gagne !\n";
         else cout << "Perdu !\n";
         if(a==d) cout << "Gagne !\n";
         else cout << "Perdu !\n";
         cout << "a: ";
         a.affiche();
         cout << "b: ";
         b.affiche();
         cout << "d: ";
         d.affiche();
         c = a+b;
         cout << "c: ";
         c.affiche();
     
         for(int i=0 ; c[i]!='\0' ; i++) cout << c[i];
         getch();
    }
    Celui ci m'affiche comme réponse :

    Perdu !
    Gagne !
    a: Bonjour b: x►L ─d: á►L Þ☼L c: Bonjour x►L ─Bonjour x►L

    Merci d'avance pour votre aide. Cordialement

  2. #2
    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
    Bonjour,
    C'est un problème classique lorsqu'on manipule des pointeurs nus. Tu as un constructeur par copie implicite qui est généré et qui ne copie pas en profondeur ton pointeur. Donc celui-ci va être libéré plusieurs fois, d'où toutes ces erreurs.
    Mais, vu le code, j'aurais tendance à poser une question : es-tu en train d'apprendre le C++ tout seul avec un livre ? Ton code comporte beaucoup de problèmes et il me semble qu'il reste quelques lacunes sur les fondamentaux.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 26
    Par défaut
    En effet j'apprends tout seul. Si vous pouvez m'éclairer un peu plus car je n'ai pas tout compris votre réponse. Cordialement

  4. #4
    Membre chevronné Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Par défaut
    Réessaye sans les gagné/perdu ça va marcher !

    Pourquoi ? Parce que tu utilise le passage par copie, qui utilise le constructeur de copie de ta variable, qui se contente de bêtement recopier chaque champs.

    Du coup, lorsque la copie et détruite, et appelle le destructeur, elle appelle
    et là, c'est la cata : ton objet original pointes désormais sur un champs désalouer.

    Au passage, tu as de la chance que ça ne plante pas...

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 26
    Par défaut
    Oui en effet ça fonctionne mais je voudrais réussir à faire fonctionner le programme sans toucher à class chaine et void main()

  6. #6
    Membre chevronné Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Par défaut
    Comment veux-tu corriger un programme sans le modifier oO !?!

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 26
    Par défaut
    Je voudrais qu'il affiche toujours gagné perdu. J'ai commencé à mofifier le code mais dorénavant le programme plante.

    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
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    #include <conio.h>
    #include <iostream>
     
    using namespace std;
     
    class chaine
    {
          private :
                  int longueur;
                  char *adr;
          public :
                 chaine();
                 chaine(char *texte);
                 void operator =(chaine &ch);
                 int operator ==(chaine ch);
                 chaine &operator +(chaine ch);
                 char &operator [](int i);
                 ~chaine();
                 void affiche();
    };
     
    chaine::chaine()      //constructeur1
    {
                          longueur=0;
                          adr = NULL;
    }
     
    chaine::chaine(char *texte)     //constructeur2
    {
                        longueur = strlen(texte)+1;
                        adr = new char[longueur];
                        strcpy(adr,texte);
    }
     
     
    void chaine::operator =(chaine &ch)
    {
         delete adr;
         longueur = ch.longueur;
         adr = new char[longueur+1];
         strcpy(adr,ch.adr);
    }
     
    int chaine::operator ==(chaine ch)
    {
        int i, res=1;
        for(i=0; (i!=(longueur+1))&&(res!=0); i++) if(adr[i]!=ch.adr[i]) res=0;
        return res;
    }
     
    chaine &chaine::operator +(chaine ch)
    {
           chaine res;
           res.longueur = longueur + ch.longueur;
           res.adr = new char[res.longueur+1];
           strncpy(res.adr,adr,res.longueur);
           strncat(res.adr,ch.adr,res.longueur);
           return res;
    }
     
    char &chaine::operator [](int i)
    {
         static char res='\0';
         if(longueur!=0) res= *(adr+i);
         return res;
    }
     
    chaine::~chaine()
    {
                     delete adr;
    }
     
    void chaine::affiche()
    {
         int i;
         for(i=0; i!=longueur; i++) cout << adr[i];
    }
     
    int main(void)
    {
         chaine a("Bonjour "),b("Maria"),c,d("Bonjour "),e;
     
         if(a==b) cout << "Gagne !\n";
         else cout << "Perdu !\n";
         if(a==d) cout << "Gagne !\n";
         else cout << "Perdu !\n";
         cout << "a: ";
         a.affiche();
         cout << "b: ";
         b.affiche();
         cout << "d: ";
         d.affiche();
         c = a+b;
         cout << "c: ";
         c.affiche();
     
         for(int i=0 ; c[i]!='\0' ; i++) cout << c[i];
         getch();
    }

  8. #8
    Membre chevronné Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Par défaut
    J'ai l'impression que tu veux faire joujoue avec des trucs qui se maîtrise que difficilement... Quit à utiliser "l'API" C standard, pourquoi n'utilise tu pas plutôt celle du c++, à savoir std::string etc... ?

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 26
    Par défaut
    Tout simplement parce que ce n'est pas dans mes cours

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 26
    Par défaut
    Je ne vois pas pourquoi ça ne marche pas mes constructeurs sont bons(je pense) donc ça ne peut venir que des opérateurs mais je ne vois pas ce qui ne va pas

  11. #11
    Membre chevronné Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Par défaut
    Ben si tu veux pas modifier ta classe, ça va pas être facil.
    Ce qui ne va pas, c'est que le prototype de operateur devrait plutôt être
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    operator(chaine const &);
    Mais je te conseil sérieuseument un tour dans la faq... Avec tout ce qui a été dit, j'ai vaguement l'impression que tes cours manques de sérieux... Sais-tu ce que le passage par référence ?

  12. #12
    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 bibeul Voir le message
    Je ne vois pas pourquoi ça ne marche pas mes constructeurs sont bons(je pense) donc ça ne peut venir que des opérateurs mais je ne vois pas ce qui ne va pas
    Salut,
    La bonne signature pour l'opérateur = est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    chaine & operator =(chaine const &ch);
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    chaine & operator =(chaine const ch);
    F.A.Q. : Comment écrire un opérateur d'affectation correct ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int operator ==(chaine ch);
    devrait retourner un bool et devrait être const (et pourrait prendre ch par référence constante):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    bool operator ==(chaine const &ch) const;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char &operator [](int i);
    devrait exister en version const et non const :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    char &operator [](int i);
    char const &operator [](int i) const;
    Il manque le constructeur par copie. Et c'est pour ça que ton code ne marche pas.
    Prenons le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    chaine a("Bonjour "),b("Maria");
         if(a==b) cout << "Gagne !\n";
    A l'heure actuel, a==b correspond à l'appel : a.operator ==(b). Comme == prend son argument par valeur et non par référence, une copie de b est créée. N'ayant pas de constructeur par copie défini, c'est celui du compilateur qui est utilisé. Il se contente de faire = sur les membres de ta classe. Donc, la copie de b a la même adresse dans adr que b. A la sortie de l'opérateur ==, la copie de b est détruite, donc le destructeur est appelé. Là, le destructeur fait un delete de adr. Donc, comme il s'agit de la même adresse que b, b se retrouve avec un pointeur libéré. L'adresse mémoire qu'il désigne va pouvoir prendre des nouvelles valeurs en fonction de ce que le programme va faire. D'où tes comportements étranges.
    Pour corriger, tu devrais faire un constructeur par copie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    chaine::chaine(chaine const &rhs_)
    :adr(rhs_.longueur?new char[rhs_.longueur+1]:0),longueur(rhs_.longueur)
    {
       strcpy(adr,rhs_.adr);
    }

    Débuter l'apprentissage du C++ avec les pointeurs est une mauvaise idée. C'est une notion délicate et il est important de maîtriser d'autres aspects avant. Je te conseille d'aller regarder la page des tutoriels ou d'essayer avec Penser en C++ ou tout autre livre présenté dans la page livre. Qu'utilises-tu actuellement pour apprendre ? Quel livre ? Quel tuto ?

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 26
    Par défaut
    Oui je sais ce que c'est ... en fait dans mon bouquin j'ai un exercice avec le code a compléter avec la partie class et main() déjà rempli donc il ne reste plus qu'à remplir la partie du milieu. Mais ce qui me perturbe ce que lorsque je retire la partie gagné/perdu la fonctionne affiche() fonctionne donc il ne doit pas manquer grand chose dans le prg pour que cela fonctionne. Ca doit être tout bête mais j'ai beau retourner le code dans tout les sens et rien. Cordialement,

  14. #14
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 26
    Par défaut
    Désolé je n'ai pas vu le dernier post je vais regardé ça de plus près cet après-midi. Merci à tous pour votre aide. Bonne journée à vous.

  15. #15
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Un dénommé Coplien a exprimé le fait que, pour qu'une classe puisse être facilement utilisée, elle devait répondre à quatre besoins fondamentaux.

    Elle doit, en effet
    1. pouvoir être construite
    2. pouvoir être copiée
    3. pouvoir être assignée
    4. pouvoir être détruite
    On parle généralement de la "forme canonique de Coplien" pour définir une classe pour laquelle on définit ces différents comportements.

    Pour être complet, Coplien a déterminé d'autres formes canoniques, mais seule celle-ci nous intéresse pour l'instant

    C'est à dire que, avant même d'envisager de créer les opérateurs [], ==, +, += etc, il faut, en tout état de cause, que tu fournisse quatre comportements donnés:
    1. un constructeur, qui peut être par défaut (ne prenant pas d'argument), ou non (c'est à dire que tu peux fournir plusieurs constructeurs )
    2. un constructeur définit le comportement d'un constructeur lorsque l'argument reçu est... un référence constante sur un objet du type de ta classe
    3. un opérateur d'affectation " = "
    4. un destructeur
    Si tu ne définis pas l'un de ces comportements, le compilateur fournira un comportement par défaut pour celui qui n'est pas définit.

    Par exemple, si tu ne délare pas le constructeur par copie pour ton objet, le compilateur en produira automatiquement un dont le comportement sera d'effectuer la copie membre à membre de ton objet, et c'est là que les problèmes commencent lorsque l'on travaille avec des pointeurs.

    En effet, un pointeur n'est jamais qu'une variable numérique entière et non signée représentant... l'adresse à laquelle on va trouver l'objet pointé.

    La copie d'un pointeur va donc "naturellement" faire en sorte que la copie et le pointeur... pointent vers la même adresse, et donc vers... la même variable.

    Or, ce n'est, définitivement, pas ce que tu souhaite ici:

    En effet, lorsque le destructeur sera appelé et qu'il effectuera un delete[] sur le pointeur, il libérera l'espace mémoire qui commence à l'adresse représentée par le pointeur, et tu te trouvera, après destruction d'un des objets (que ce soit de la copie ou de l'"original"), avec l'autre objet dont le pointeur pointe vers... une adresse mémoire invalide, avec, comme conséquence que:
    1. Si tu essaye d'accéder au contenu de cet espace mémoire, il puisse être utilisé à "autre chose"
    2. Si tu essaye (par exemple du fait de la destruction de l'objet "survivant") de libérer l'espace mémoire pointé par le pointeur, tu te trouve dans une situation où tu essaye de... libérer à nouveau un espace mémoire déjà libéré.
    Tu auras donc compris que, lorsque tu gères la mémoire dynamiquement, tu te trouves face à l'obligation de faire en sorte que... chaque objet dispose d'un espace mémoire alloué dynamiquement qui... lui est propre

    Ainsi, ta classe chaine qui, en dehors des opérateurs ==, +, [],+=,... doit au minimum être composée de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class chaine
    {
        public:
             chaine(); //constructeur trivial (par défaut)
             chaine(const char *); //constructeur prenant un pointeur sur caracteres
             chaine(const chaine &); // constructeur par copie
             chaine& operator=(chaine  const  &); //operateur d'affectation
             ~chaine(); // destructeur
        private:
             char * str_; // le pointeur vers le tableau de caractères
             size_t size_;// le nombre de caractères représentatifs de la chaine
    };
    Le constructeur "trivial" sera implémenté sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    chaine::chaine():str_(0),size_(0)
    {
    }
    Le constructeur prenant un pointeur de caractères sera implémenté sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    chaine::chaine(const char * tab):str(new char[strlen(tab)+1],
                                     size_(strlen(tab))
    {
        /* Copie du contenu */
        /* on peut le faire avec l'api C */
        strcpy(str_,tab);
        /* ou " a mano " */
        for(size_t i=0;i<size_;++i)
            str_[i]=tab[i];
        /* on n'oublie cependant pas de mettre le '\0' terminal */
        str_[size_]='\0';
    }
    le destructeur sera implémenté sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    chaine::~chaine()
    {
        delete[] str_;// libération de la mémoire
        /* et remise à zero du pointeur et de la taille */
        str_=0;
        size_ = 0;
    }
    Le constructeur par copie sera, quant à lui, implémenté sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    chaine::chaine(chaine const & str):str_(new char[str_.size_+1])
                                       size_(str.size_)
    {
        /* on peut utiliser l'api C */
        strcnpy(str_,str.str_);
        /* ou le faire "a mano" */
        for(size_t i=0;i<size_;++i)
            str_[i]=str.str_[i];
        /* on n'oublie cependant pas de mettre le '\0' terminal */
        str_[size_]='\0';
     
    }
    Enfin, il nous reste un dernier problème... l'opérateur d'affectation.

    En effet, nous devons avoir la certitude qu'un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int main()
    {
        chaine str1("bonjour");
        chaine str2("tout le monde");
        str1=str2;
        /* utilisation de str1 ou de str2 */
        return 0;
    }
    ne posera pas de problème, ce qui implique
    1. que str1 et str2 ne partagent pas la mémoire allouée à leur pointeurs str_ respectifs
    2. que l'assignation d'une nouvelle valeur à str1 ne provoque pas de fuites mémoire.
    Le plus "facile" pour avoir cette certitude est d'utiliser l'idiome "copy and swap" qui consiste à:
    1. s'arranger pour créer une copie temporaire de la valeur à obtenir
    2. intervertir les membres de l'objet en cours et de cette copie temporaire
    3. profiter de la destruction de la copie temporaire pour libérer la mémoire qui était allouée à l'origine à l'objet en cours
    4. renvoyer l'objet en cours

    L'opérateur d'affectation serait donc, idéalement, implémenté sous une forme proche de
    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
    chaine& chaine::operator= (chaine const & to)
    {
        /* utilisons le constructeur par copie */
        chaine copie(to);
        /* intervertissons les différents membres
         * NOTA: nous pourrions utiliser l'algorithme swap, fournit par le
         * standard ;)
         */
         char * ptr=copie.str_;
         copie.str_=str_;
         str_=ptr;
         size_t s=copie.size_;
         copie.size_=size_;
         size_=s;
        return *this;
    }
    ou nous pourrions profiter du fait que le passage par valeur provoque la copie (et donc l'appel au constructeur par copie) de l'objet, sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class chaine
    {
        public:
             /* à part l'opérateur =, le reste est identique à précédemment */
             chaine& operator=(chaine ); //operateur d'affectation
    };
    et l'opérateur d'affectation serait alors implémenté sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    chaine & chaine::operator=(chaine cpy) // l'appel au constructeur par copie
                                           // est implicite
    {
         char * ptr=cpy.str_;
         cpy.str_=str_;
         str_=ptr;
         size_t s=cpy.size_;
         cpy.size_=size_;
         size_=s;
         return *this;
    }
    Tu pourrais, aussi, envisager une surcharge de l'opérateur d'affectation de manière à autoriser un code proche de
    chaine str;
    str="salut tout le monde";
    qui serait déclaré (dans la définition de la classe) sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    chaine & operator=(const char *);
    et implémenté sous une forme proche de
    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
    chaine & chaine::operator=(const char * tab)
    {
        /* NOTA: il existe d'autres solutions, mais cela ne ferait qu'augmenter
         * les explications à fournir... 
         * et mon intervention est déjà longue assez :D
         */
        chaine temp(tab); // construction du temporaire
         char * ptr=temp.str_;
         temp.str_=str_;
         str_=ptr;
         size_t s=temp.size_;
         temp.size_=size_;
         size_=s;
         return *this;
    }
    Une fois que ces quatre comportements seront fournis, tu pourra réfléchir sereinement à ce que ta classe doit permettre d'autre
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  16. #16
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 26
    Par défaut
    Merci beaucoup pour votre aide j'ai ajouté le constructeur par copie (en effet c'est cela qui manquait) et ça fonctionne parfaitement. Merci surtout à Koala et 3DArchi pour vos explications. Je vous souhaite une bonne journée.

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

Discussions similaires

  1. Portabilitée : Surcharge opérateur de comparaison
    Par Dimitri_87 dans le forum C++
    Réponses: 11
    Dernier message: 15/12/2006, 16h14
  2. Surcharge opérateur +
    Par nunurs83 dans le forum C++
    Réponses: 6
    Dernier message: 31/10/2006, 09h48
  3. [Débutant]Surcharge opérateur +
    Par Geolem dans le forum Débuter
    Réponses: 13
    Dernier message: 05/12/2005, 10h16
  4. surcharge opérateur << et >>
    Par Azharis dans le forum Débuter
    Réponses: 11
    Dernier message: 02/11/2005, 21h22
  5. Surcharge opérateurs
    Par ghostdogpr dans le forum C++
    Réponses: 5
    Dernier message: 18/03/2005, 11h51

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