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 :

afficher attribut de la classe fille dans un vecteur qui utilise la classe mère


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Inscrit en
    Avril 2011
    Messages
    52
    Détails du profil
    Informations forums :
    Inscription : Avril 2011
    Messages : 52
    Points : 38
    Points
    38
    Par défaut afficher attribut de la classe fille dans un vecteur qui utilise la classe mère
    Bonjour,
    j'ai une classe Mail
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    class Mail{
    protected :
     string message;
    public:
     string getmessage(){return message;}
    };
    et une classe MailRecu qui hérite de la classe Mail :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    #include "Mail.h"
    class MailRecu:public Mail
    {
        private:
        string source;
        public:
        string getsource(){return source;}
    };
    et une autre classe Compte avec un vecteur qui va contenir tous les emails
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    #include "Mail.h"
    #include "MailRecu.h"
    #include<vector>
    using namespace std;
     
    class compte
    {
    private:
     
        int numero;
        string nomCompte;
        vector <Mail *> mails;
    };
    je veux afficher l'attribut source dans la classe Compte grâce à la méthode getsource() ainsi j'ai fait cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
     cout <<mails[i]->getsource();
    mais l'attribut message s'affiche normalement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
     cout<<mails[i]->getmessage();
    voici l'erreur qui s'affiche
    'class Mail' has no member named 'getsource'|

    comment faire pour afficher source dans la classe Compte?

  2. #2
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Salut,

    C'est normal, car si la classe fille connait parfaitement la classe mere (l'héritage est une relation EST-UN, c'est à dire qu'un objet du type de la classe dérivée peut etre utilisé partout où un objet du type de la classe mère est utilisé ), la classe mère n'a strictement aucun moyen de connaitre... les classes qui en dérivent .

    Ceci dit, je ne vois pas vraiment pourquoi faire dériver MailRecu de Mail.

    A vrai dire, je ne vois purement et simplement pas pourquoi créer MailRecu

    Je m'explique : un mail est un mail, qu'il soit reçu, envoyé, brouillon ou quoi ou qu'est-ce.

    Or, il n'y a strictement aucune raison de maintenir dans une même collection les mails reçus, les mails envoyés, les mails "brouillons", pour la simple et bonne raison que... tu ne voudras jamais avoir que la liste d'une de ces catégories, sans avoir que faire des autres.

    Dés lors, pourquoi ne pas donner à mail tout ce qui lui permet de travailler

    Ta classe mail pourrait très bien ressembler à quelque chose comme
    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
    class Mail
    {
        public:
            /* je ne met que les accesseurs ;) */
            std::string const & from() const{return from_;}
            std::string const & to() const{return to_;}
            std::string const & title() const{return title_;}
            std::vector<std::string>::const_iterator messageBegin() const
            {
                 return lines_.begin();
            }
            std::vector<std::string>::const_iterator messageEnd() const
            {
                 return lines_.end();
            }
        private:
            std::string from_;
            std::string to_;
            std::string title_;
            std::vector<std::string> lines_;
    };
    Ils seraient gérés par un "gestionnaire" (une instance de gestionnaire par "type" de mail ) 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
    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
    class MailManager
    {
        public:
             /* le type ID est une manière pour toi d'identifier n'importe quel
              * mail de manière unique... à toi de déterminer le meilleur moyen
              * d'y arriver ;)
              */
             void addMail(Id const & id, Mail const & mail)
             {
                 /* je me base sur l'idée qu'on a une std::map, mais, à la 
                  * réflexion, un boost multi_index serait très certainement plus 
                  * intéressant :D
                  */
                 items_.insert(std::make_pair(id,mail));
             }
             std::map<Id,Mail>::const_iterator begin() const
             {
                 returns items_.begin();
             }
             std::map<Id,Mail>::const_iterator end() const
             {
                 returns items_.end();
             }
             void remove(Id const & id)
             {
                 items_.erase(items_.find(id));
             }
             void remove(std::map<Id,Mail>::const_iterator &)
             {
                 items_.erase(it);
             }
             std::map<Id,Mail>::const_iterator find(Id const & id) const
             {
                 return items_.find(id);
             }
             void clear()
            {
                items_.clear();
            }
             /* il faudra sans doute prévoir d'autres manières de trouver
              * des mails : sur base de l'expéditeur, du récepteur, du message,
              * du titre ou que sais-je :D
              */
        private: 
            std::map<Id, Mail> items_;  
    };
    Et, au niveau du client, tu aurais donc quelque chose comme
    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
    class Client
    {
        public:
            /* à faire pour received_,send_ draft_ et trash ;) */
            void addToReceived(Mail const & mail)
            {
                 Id id,createId(mail);
                 received_.addMail(id,mail);
            }
            /* à faire pour received_,send_ draft_ et trash ;) */
            std::map<Id,Mail>::const_iterator receivedBegin() const
            {
                return received_.begin();
            }
            /* à faire pour received_,send_ draft_ et trash ;) */
            std::map<Id,Mail>::const_iterator receivedEnd() const
            {
                return received_.end();
            }
            template <iterator>
            void sendToTrash(iterator begin, iterator end)
            {
                while(begin!= end)
                {
                    sendToTrash(*begin);
                }
            }
            void sendToTrash(Id const & id)
            {
               std::map<Id::mail>::const_iterator it = received_.find(id);
               if(it != received_.end())
               {
                   trash_.addMail(it->second);
                   received_.erase(it);  
                   return 0;
               }
               it = send_.find(id);
               if(it != send_.end())
               {
                   trash_.addMail(it->second);
                  send_.erase(it);  
                   return 0;
               }
               it = draft_.find(id);
               if(it != draft_.end())
               {
                   trash_.addMail(it->second);
                  draft_.erase(it);  
                   return 0;
               }
            }
            /* surement plein d'autres trucs sympa ;) */
        private:
             Id createId(Mail const & mail) const
             {
                 /* un algorithme te permettant de créer un identifiant
                  * strictement unique pour n'importe quel mail indépendamment 
                  * du manager qui va le prendre en charge
                  */
             }
            MailManager received_; // le gestionnaire de mails recus
            MailManager send_; // le gestionnaire de mails envoyés
            MailManager draft_; // le gestionnaire de brouillons
            MailManager trash_; // le gestionnaire de mails envoyés à la poubelle
    };
    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

  3. #3
    Membre éprouvé

    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 533
    Points : 1 086
    Points
    1 086
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    class Mail {
        // (...)
        virtual string getsource() = 0;
    }
    Après, on peut effectivement s'interroger sur la conception du code.
    Les "propriétés" d'un mail sont-elles différentes en fonction de son emplacement (Inbox, Drafts, Corbeille, Archives, ...) ? Si je souhaite déplacer un mail, dois-je "changer sa classe" ?

  4. #4
    Nouveau membre du Club
    Inscrit en
    Avril 2011
    Messages
    52
    Détails du profil
    Informations forums :
    Inscription : Avril 2011
    Messages : 52
    Points : 38
    Points
    38
    Par défaut
    Merci beaucoup koala01 pour la réponse , ça fait plaisir.
    eh bien j'ai dérivé la classe mailrecu de la classe mail car un mail recu est un email mais il a des attributs en plus qui sont état (lu ou non lu) et source , j'ai une autre classe mailenvoye qui est derivée aussi de la classe mail et qui a d'autres attributs comme destinataire .
    la classe compte contient un vecteur de type mail* .
    il n'y a aucun moyen d'afficher source et destinataire dans compte ?
    il n'y a pas un moyen de tester si le vecteur contient des mails recus ou des mails envoye ou un mail ( brouillon) ?

  5. #5
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Citation Envoyé par amAtunisian Voir le message
    Merci beaucoup koala01 pour la réponse , ça fait plaisir.
    De rien
    eh bien j'ai dérivé la classe mailrecu de la classe mail car un mail recu est un email mais il a des attributs en plus qui sont état (lu ou non lu) et source , j'ai une autre classe mailenvoye qui est derivée aussi de la classe mail et qui a d'autres attributs comme destinataire .
    Déjà, les attributs comme destinataire, source, BCC, pieces jointes sont de toutes façons communs à tous les mails : ce sont des informations qui font partie intégrante du mail, la seule différence entre un mail envoyé (ou à envoyer) et un mail reçu étant... que la source est connue pour l'un et le destinataire pour l'autre.

    De plus, le problème en essayant de créer une hiérarchie de mails en fonction de leur source/destination ou de leur état (lu / brouillon / envoyé), c'est : que va-t-il se passer lorsque tu voudras faire passer un mail de "brouillon" à "envoyé" ou à "à envoyer"

    Pour passer de l'un à l'autre, il faudra, fatalement, créer un nouvel objet de classe différente, alors que les différences portent simplement sur... un état

    la classe compte contient un vecteur de type mail* .
    il n'y a aucun moyen d'afficher source et destinataire dans compte ?
    Pourquoi n'avoir qu'un seul vecteur de mail * et une hiérarchie plus ou moins complexe lorsqu'il suffit d'avoir plusieurs vecteurs de mail (pointeur ou non) avec une seule classe, et les faire passer de l'un à l'autre en fonction de leur état interne

    L'héritage est la relation la plus forte qui puisse exister entre deux classes: il ne faut donc pas l'utiliser à la légère, et il ne faut pas non plus oublier le principe connu (en extrem programming) sous le sigle KISS (Keep It Simple, Stupid), qui te rappelle en permanence que la solution la plus simple est la moins compliquée... heu, pardon, la meilleure!
    il n'y a pas un moyen de tester si le vecteur contient des mails recus ou des mails envoye ou un mail ( brouillon) ?
    La meilleure solution serait, non pas de créer une hiérarchie de mails, mais de créer une hiérarchie d'états qui seraient utilisés par le mail (une seule classe mail, pouvant utiliser un des états définis de manière indifférente).

    Le problème de cette solution, c'est que cela donne une responsabilité à la classe mail qu'elle n'a pas à avoir : le mail en lui-même n'a aucun besoin de savoir si c'est un brouillon, s'il a été envoyé ou non ou... s'il a été lu.

    Si "quelque chose" doit garder l'état du mail, c'est bien la classe qui aura la charge de... gérer l'ensemble des mails: elle mettrait en commun le mail, son état, et une donnée permettant d'identifier chaque mail de manière unique ( éventuellement d'autres données directement issues de mail) de sorte à pouvoir les trier selon les souhaits de l'utilisateur.


    L'idéal étant, comme je l'ai indiqué dans ma réponse précédente, de faire en sorte que ce "quelque chose" ne manipule que les mails issus d'une catégorie particulière (recus, envoyés, brouillons, supprimés,... )
    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

Discussions similaires

  1. Réponses: 1
    Dernier message: 20/09/2013, 10h02
  2. Réponses: 5
    Dernier message: 07/06/2012, 21h49
  3. Réponses: 6
    Dernier message: 22/07/2010, 15h17
  4. Réponses: 21
    Dernier message: 22/10/2007, 10h10
  5. Utilisation de classes C++ dans linux
    Par DestinyWar45 dans le forum Linux
    Réponses: 4
    Dernier message: 10/10/2005, 13h33

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