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 :

Surcharge d'opérateurs


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Juin 2014
    Messages
    219
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable de compte

    Informations forums :
    Inscription : Juin 2014
    Messages : 219
    Par défaut Surcharge d'opérateurs
    Bonjour.

    Je suis parti de cette video :

    où je tente de pousser l'exercice un peu plus loin en surchargeant l'opérateur "<<" agissant sur les "struct Comment" pour faire un effet de mise en page et je rencontre un soucis dont je ne trouve la cause !

    Je déclare une struct Comment dont les instances prennent 2 paramètre (1 string et 1 int optionnel).
    Ensuite, je surcharge l'opérateur << qui est supposé afficher le commentaire avec un petit effet de mise en page.
    Le code suivant fonctionne :
    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
    #include <iostream>
    #include <list>
    #include <string>
    using namespace std;
     
    struct Comment
    {
        string Str;
        int Symbol;
        Comment(const string &str, const int &symbol= 2)
        {
            Str = str;
            Symbol = symbol;
        }
    };
     
    ostream &operator<<(ostream &COUT, Comment &comment)
    {
        int size = comment.Str.size();
        for (int i = 0; i < size; i++)
        {
            COUT << comment.Symbol;
        }
        COUT << endl << comment.Str << endl;
        for (int i = 0; i < size; i++)
        {
            COUT << comment.Symbol;
        }
        return COUT;
    }
     
    struct YoutubeChannel
    {
        string Name;
        int SubscribersCount;
     
        YoutubeChannel(string name, int subscribersCount)
        {
            Name = name;
            SubscribersCount = subscribersCount;
        }
        bool operator==(const YoutubeChannel channel) const
        {
            return this->Name == channel.Name;
        }
    };
     
    ostream &operator<<(ostream &COUT, YoutubeChannel &ytChannel)
    {
        COUT << "Name: " << ytChannel.Name << endl;
        COUT << "SubscribersCount: " << ytChannel.SubscribersCount << endl;
        ;
        return COUT;
    }
     
    struct MyCollection
    {
        list<YoutubeChannel> myChannels;
        void operator+=(YoutubeChannel &channel)
        {
            this->myChannels.push_back(channel);
        }
        void operator-=(YoutubeChannel &channel)
        {
            this->myChannels.remove(channel);
        }
    };
     
    ostream &operator<<(ostream &COUT, MyCollection &myCollection)
    {
        for (YoutubeChannel ytChannel : myCollection.myChannels)
        {
            COUT << ytChannel << endl;
        }
        return COUT;
    }
     
    int main(void)
    {
        YoutubeChannel yt1("CodeBeauty", 75000);
        YoutubeChannel yt2("Second channel", 70);
        YoutubeChannel yt3("third channel", 0);
     
        MyCollection myCollection;
        myCollection += yt1;
        myCollection += yt3;
        myCollection += yt2;
        cout << myCollection;
        myCollection -= yt1;
        Comment comment("Printing after removing a channel", 9);
        cout << comment;
        cout << endl;
        cout << myCollection;
     
        return 0;
    }

    Par contre celui-ci refuse de passer au compilateur alors que je ne tente que de remplacer mon paramètre optionnel "Symbol" int par un char :
    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
    #include <iostream>
    #include <list>
    #include <string>
    using namespace std;
     
    struct Comment
    {
        string Str;
        char Symbol;
        Comment(const string &str, const char &symbol= '&')
        {
            Str = str;
            Symbol = symbol;
        }
    };
     
    ostream &operator<<(ostream &COUT, Comment &comment)
    {
        int size = comment.Str.size();
        for (int i = 0; i < size; i++)
        {
            COUT << comment.Symbol;
        }
        COUT << endl << comment.Str << endl;
        for (int i = 0; i < size; i++)
        {
            COUT << comment.Symbol;
        }
        return COUT;
    }
     
    struct YoutubeChannel
    {
        string Name;
        int SubscribersCount;
     
        YoutubeChannel(string name, int subscribersCount)
        {
            Name = name;
            SubscribersCount = subscribersCount;
        }
        bool operator==(const YoutubeChannel channel) const
        {
            return this->Name == channel.Name;
        }
    };
     
    ostream &operator<<(ostream &COUT, YoutubeChannel &ytChannel)
    {
        COUT << "Name: " << ytChannel.Name << endl;
        COUT << "SubscribersCount: " << ytChannel.SubscribersCount << endl;
        ;
        return COUT;
    }
     
    struct MyCollection
    {
        list<YoutubeChannel> myChannels;
        void operator+=(YoutubeChannel &channel)
        {
            this->myChannels.push_back(channel);
        }
        void operator-=(YoutubeChannel &channel)
        {
            this->myChannels.remove(channel);
        }
    };
     
    ostream &operator<<(ostream &COUT, MyCollection &myCollection)
    {
        for (YoutubeChannel ytChannel : myCollection.myChannels)
        {
            COUT << ytChannel << endl;
        }
        return COUT;
    }
     
    int main(void)
    {
        YoutubeChannel yt1("CodeBeauty", 75000);
        YoutubeChannel yt2("Second channel", 70);
        YoutubeChannel yt3("third channel", 0);
     
        MyCollection myCollection;
        myCollection += yt1;
        myCollection += yt3;
        myCollection += yt2;
        cout << myCollection;
        myCollection -= yt1;
        Comment comment("Printing after removing a channel", 'F');
        cout << comment;
        cout << endl;
        cout << myCollection;
     
        return 0;
    }
    Je ne comprends absolument pas pourquoi cela refuse de fonctionner .
    Quelqu'un pourrait il m'aiguiller sur mon erreur ou bien pourquoi cela n'est pas sensé fonctionner ?

  2. #2
    Expert confirmé
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 532
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 532
    Par défaut
    pourquoi ne pas passer simplement const string & Symbol="&" ?
    Le problème de passer un char c'est que la variable locale à la structure Comment est de type string et elle ne trouve pas le caractère de terminaison en passant un char.
    En C/C++ les chaînes de caractères se terminent par '\0'.
    Puis on évite les structures car les membres de la classe sont publics par défaut

  3. #3
    Membre confirmé
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Juin 2014
    Messages
    219
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable de compte

    Informations forums :
    Inscription : Juin 2014
    Messages : 219
    Par défaut
    Merci beaucoup pour la réponse rapide.

    Je me doutait qu'il pouvait y avoir une subtilité avec char et j'avais donc essayé avec string. J'avais cependant du faire une bourde quelque part car ça ne fonctionnait pas quand même.

    Je ne comprend pas trop pourquoi tu dis "la variable locale à la structure Comment est de type string"


    En tout cas, ça fonctionne comme je le souhaite;
    Merci.
    Sinon au lieu d'utiliser une struct, j'aurai du utiliser une class ? J'ai essayé mais n'ai pour l'instant pas réussi à faire un code fonctionnel.

    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
    104
    105
    106
    107
    108
    #include <iostream>
    #include <list>
    #include <string>
    using namespace std;
     
    struct Comment
    {
        string Str;
        string Symbol;
        Comment(const string &str, const string &symbol = "*")
        {
            Str = str;
            Symbol = symbol;
        }
    };
     
    ostream &operator<<(ostream &COUT, Comment &comment)
    {
        int size = comment.Str.size();
        for (int i = 0; i < size; i++)
        {
            COUT << comment.Symbol;
        }
     
        COUT << endl
             << comment.Str << endl;
        for (int i = 0; i < size; i++)
        {
            COUT << comment.Symbol;
        }
     
        return COUT;
     
        /*void print_symbol(const Comment &comment)
        {
            int size = comment.Str.size();
            for (int i = 0; i < size; i++)
            {
                COUT << comment.Symbol;
            }
        }*/
    }
     
    struct YoutubeChannel
    {
        string Name;
        int SubscribersCount;
     
        YoutubeChannel(string name, int subscribersCount)
        {
            Name = name;
            SubscribersCount = subscribersCount;
        }
        bool operator==(const YoutubeChannel channel) const
        {
            return this->Name == channel.Name;
        }
    };
     
    ostream &operator<<(ostream &COUT, YoutubeChannel &ytChannel)
    {
        COUT << "Name: " << ytChannel.Name << endl;
        COUT << "SubscribersCount: " << ytChannel.SubscribersCount << endl;
        ;
        return COUT;
    }
     
    struct MyCollection
    {
        list<YoutubeChannel> myChannels;
        void operator+=(YoutubeChannel &channel)
        {
            this->myChannels.push_back(channel);
        }
        void operator-=(YoutubeChannel &channel)
        {
            this->myChannels.remove(channel);
        }
    };
     
    ostream &operator<<(ostream &COUT, MyCollection &myCollection)
    {
        for (YoutubeChannel ytChannel : myCollection.myChannels)
        {
            COUT << ytChannel << endl;
        }
        return COUT;
    }
     
    int main(void)
    {
        YoutubeChannel yt1("CodeBeauty", 75000);
        YoutubeChannel yt2("Second channel", 70);
        YoutubeChannel yt3("third channel", 0);
     
        MyCollection myCollection;
        myCollection += yt1;
        myCollection += yt3;
        myCollection += yt2;
        cout << myCollection;
        myCollection -= yt1;
        Comment comment("Printing after removing a channel", "%");
        cout << comment;
        cout << endl;
        cout << myCollection;
     
        return 0;
    }

  4. #4
    Expert confirmé
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 532
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 532
    Par défaut
    bonsoir la variable locale à la struct Comment c'est String "Str"

  5. #5
    Membre confirmé
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Juin 2014
    Messages
    219
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable de compte

    Informations forums :
    Inscription : Juin 2014
    Messages : 219
    Par défaut
    Selon vos conseils, j'ai transformé mes struct en class, mais ça ne compile pas à cause de ces lignes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        bool operator==(const YoutubeChannel channel) const
        {
            return this->getName() == channel.getName();
        }
    Pour mes autres struct, celà a fonctionné. Mais je ne suis pas du tout à l'aise avec ce "this->"

    Code complet :
    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
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    #include <iostream>
    #include <list>
    #include <string>
    using namespace std;
     
    class Comment
    {
    private:
        string Str;
        string Symbol;
     
    public:
        Comment(const string &str, const string &symbol = "*")
        {
            Str = str;
            Symbol = symbol;
        }
        //accesseur
        string getStr(void)
        {
            return Str;
        }
        string getSymbol(void)
        {
            return Symbol;
        }
    };
     
    ostream &operator<<(ostream &COUT, Comment &comment)
    {
        int size = comment.getStr().size();
        for (int i = 0; i < size; i++)
        {
            COUT << comment.getSymbol();
        }
     
        COUT << endl
             << comment.getStr() << endl;
        for (int i = 0; i < size; i++)
        {
            COUT << comment.getSymbol();
        }
     
        return COUT;
     
        /*void print_symbol(const Comment &comment)
        {
            int size = comment.Str.size();
            for (int i = 0; i < size; i++)
            {
                COUT << comment.Symbol;
            }
        }*/
    }
     
    class YoutubeChannel
    {
    private:
        string Name;
        int SubscribersCount;
     
    public:
        YoutubeChannel(string name, int subscribersCount)
        {
            Name = name;
            SubscribersCount = subscribersCount;
        }
        //accesseur :
        string getName(void)
        {
            return Name;
        }
     
        int getSubscribersCount(void)
        {
            return SubscribersCount;
        }
     
        bool operator==(const YoutubeChannel channel) const
        {
            return this->getName() == channel.getName();
        }
    };
     
    ostream &operator<<(ostream &COUT, YoutubeChannel &ytChannel)
    {
        COUT << "Name: " << ytChannel.getName() << endl;
        COUT << "SubscribersCount: " << ytChannel.getSubscribersCount() << endl;
        ;
        return COUT;
    }
     
    struct MyCollection
    {
        list<YoutubeChannel> myChannels;
        void operator+=(YoutubeChannel &channel)
        {
            this->myChannels.push_back(channel);
        }
        void operator-=(YoutubeChannel &channel)
        {
            this->myChannels.remove(channel);
        }
    };
     
    ostream &operator<<(ostream &COUT, MyCollection &myCollection)
    {
        for (YoutubeChannel ytChannel : myCollection.myChannels)
        {
            COUT << ytChannel << endl;
        }
        return COUT;
    }
     
    int main(void)
    {
        YoutubeChannel yt1("CodeBeauty", 75000);
        YoutubeChannel yt2("Second channel", 70);
        YoutubeChannel yt3("third channel", 0);
     
        MyCollection myCollection;
        myCollection += yt1;
        myCollection += yt3;
        myCollection += yt2;
        cout << myCollection;
        myCollection -= yt1;
        Comment comment("Printing after removing a channel", "%");
        cout << comment;
        cout << endl;
        cout << myCollection;
     
        return 0;
    }

  6. #6
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 770
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 770
    Par défaut
    Ton problème est trivial "error: passing ‘const YoutubeChannel’ as ‘this’ argument discards qualifiers [-fpermissive]"

    En gros, ton operateur == dit qu'il ne modifiera pas la classe (constant). Or ta méthode getName() ne garantie pas l'immutabilité de ta classe.
    1 méthode/objet constant(e) doit appeler que des méthodes constantes.

    Comment faire ? Je ne sais pas soit refaire la logique de ta classe, soit passer par 1 const_cast.


    Citation Envoyé par hary66 Voir le message
    Sinon au lieu d'utiliser une struct, j'aurai du utiliser une class ?
    En C++, la seule différence entre 1 struct et 1 class, c'est l'encapsulation : publique et privée respectivement.


    Citation Envoyé par hary66 Voir le message
    Mais je ne suis pas du tout à l'aise avec ce "this->"
    Le this est optionnel. Dans ton code, tu n'en as pas besoin

    Il est là pour lever les ambiguïtés pour différencier les attributs/ méthodes de ta classe des paramètres qui ont le même nom.
    Souvent on rajoute 1 underscore à la fin aux attributs ou 1 "input" par exemple aux paramètres.

    Il sert aussi à retourner/ passer 1 pointeur/ reférence de la classe.

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 02/02/2020, 18h22
  2. Réponses: 16
    Dernier message: 19/02/2010, 09h40
  3. Demande d'aide pour débutant.
    Par pixee dans le forum jQuery
    Réponses: 6
    Dernier message: 31/07/2009, 10h13
  4. [PHP 5.3] Demande aide pour un débutant
    Par xenon1405 dans le forum Langage
    Réponses: 3
    Dernier message: 03/06/2009, 14h48
  5. demande d'aide pour débutant
    Par libremax dans le forum Langage
    Réponses: 6
    Dernier message: 19/11/2008, 19h03

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