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 :

heritage et lien de composition


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite Avatar de slim
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2002
    Messages
    938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2002
    Messages : 938
    Par défaut heritage et lien de composition
    salut tout le monde,

    je suis en train de coder un projet de gestion d'une videotheque. et j'aimerais avoir votre aide pour quelque chose.

    Exemple :
    j'ai une classe mère "video", une classe fille "film" et une classe acteurs (lien de composition). voila une partie du diagramme avec les classes concernées :




    et voila comment j'ai codé ces classes :

    video.h
    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
    #ifndef VIDEO_H
    #define VIDEO_H
     
    class video
    {
        protected: 
            chaine titre;
            int duree;
            int nb_exemplaires;
            chaine sujet;
    	public:
    		// class constructor
    		video();
    		video(chaine titre2, int duree2, int nbexemp, chaine sujet2);
    		video(const video & vid);
    		//accesseurs
    		chaine gettitre() const {return titre;}
    		int getduree() const {return duree;}
    		int getnbexemp() const {return nb_exemplaires;}
    		chaine getsujet() const {return sujet;}
    		//mutateurs :
    		void settitre(const chaine & titre2) {titre = titre2;}
    		void setduree(const int & duree2) {duree = duree2;}
    		void setnbexemp(const int & nbexemp) {nb_exemplaires = nbexemp;}
    		void setsujet(const chaine & sujet2) {sujet = sujet2;}
    		void setvideo(chaine titre2, int duree2, int nbexemp, chaine sujet2);
    		//surcharge des opérateurs :
    		video & operator = (const video & vid);
    		bool operator == (const video & vid);
            friend ostream & operator << (ostream & os, video & vid)
                    {os <<vid->titre<<" "<<vid->duree<<endl<<vid->nb_exemplaires<<endl<<vid->sujet<<endl;
                    return os;}
            friend istream & operator >> (istream & is, video & vid);
            void afficher() const {cout<< (video*) this;}
            void afficherdetails() const {cout<<"Titre du film : "<<titre<<endl<<"Duree : "<<duree<<endl<<"Nombre d'exemplaires : "<<endl<<nb_exemplaires<<endl<<"Sujet : "<<sujet<<endl<<endl;}
     
    };
     
    #endif // VIDEO_H
    video.cpp
    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
    #include "video.h"
    /*
    chaine titre;
    int duree;
    int nb_exemplaires;
    chaine sujet; */
     
    video::video() : titre(), sujet()
    {
        duree = 0;
        nb_exemplaires = 0;
    }
    video::video(chaine titre2, int duree2, int nbexemp, chaine sujet2)
    {
        titre = titre2;
        duree = duree2;
        nb_exemplaires = nbexemp;
        sujet = sujet2;
    }
    video::video(const video & vid)
    {
        titre = vid.titre;
        duree = vid.duree;
        nb_exemplaires = vid.nb_exemplaires;
        sujet = vid.sujet;
    }
    void video::setvideo(chaine titre2, int duree2, int nbexemp, chaine sujet2)
    {
        titre = titre2;
        duree = duree2;
        nb_exemplaires = nbexemp;
        sujet = sujet2;
    }
    const video & video::operator = (const video & vid)
    {
        titre = vid.titre;
        duree = vid.duree;
        nb_exemplaires = vid.nb_exemplaires;
        sujet = vid.sujet;
        return *this;
    }
    bool video::operator == (const video & vid)
    {
        return titre==vid.titre && duree==vid.duree && nb_exemplaires==vid.nb_exemplaires && sujet==vid.sujet;
    }
    friend istream & video::operator >> (istream & is, video & vid)
    {
        chaine titre2;
        int duree2;
        int nbexemp;
        chaine sujet2;
        cout<<"Titre du film : ";
        is>>titre2;
        cout<<"Durée : ";
        is>>duree2;
        cout<<"Nombre d'exemplaires : ";
     
        is>>nbexemp;
        cout<<"Sujet : ";
        is>>sujet2;
        video vid2(titre2, duree2, nbexemp, sujet2);
        vid = vid2;
        return is;
    }
    film.h

    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
    #ifndef FILM_H
    #define FILM_H
     
    #include "video.h"
     
    class film : public video
    {
    	private:
    	    chaine genre;
    	    chaine realisateur;
    	    acteurs acteur;
        public:
            film();
            film(chaine genre2, chaine real, acteurs nouvacteur, chaine nouvtitre, int nouvduree, int nouvnb_exemplaires, chaine nouvsujet);
            film(chaine genre2, chaine real, chaine nouvnom, chaine nouvprenom,chaine nouvtitre, int nouvduree, int nouvnb_exemplaires, chaine nouvsujet);
            film(const film & film2);
            //accesseurs :
            chaine getgenre() const {return genre;}
            chaine getrealisateur() const {return realisateur;}
            chaine getnomact() const {return acteur.getnom();}
            chaine getprenomact() const {return acteur.getprenom();}
        //... pas encore terminée.... je bloque        
     
     
    };
     
    #endif // FILM_H
    film.cpp
    pas encore codé

    acteurs.h

    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
    #ifndef ACTEURS_H
    #define ACTEURS_H
     
    class acteurs
    {
        private:
            chaine nom;
            chaine prenom;
    	public:
    		acteurs()
    		acteurs(chaine nom2, chaine prenom2);
    		acteurs(const acteurs & act);
    		//accesseurs et mutateurs :
     		chaine getnom() const {return nom;}
     		chaine getprenom() const {return prenom;}
     		void setnom(const chaine & n);
     		void setprenom(const chaine & p);
     		//surcharge des operateurs :
     		acteurs & operator = (const acteurs & act);
     		bool operator == (const acteurs & act);
     		friend ostream & operator << (ostream & os, const acteurs & act);
     		friend istream & operator >> (istream & is, const acteurs & act);
    };
     
    #endif // ACTEURS_H
    acteurs.cpp
    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
    #include "acteurs.h" 
    /*
    chaine nom;
    chaine prenom;
    */
    acteurs::acteurs() : nom(), prenom()
    {
     
    }
    acteurs::acteurs(chaine nom2, chaine prenom2)
    {
        nom = nom2;
        prenom = prenom2;
    }
    acteurs::acteurs(const acteurs & act)
    {
        nom = act.nom;
        prenom = act.prenom;
    }
    void acteurs::setnom(chaine nom2)
    {
        nom = nom2;
    }
    void acteurs::setprenom(const chaine & p)
    {
        prenom = prenom2;
    }
    acteurs & acteurs::operator = (const acteurs & act)
    {
        nom = nom2;
        prenom = prenom2;
        return *this;
    }
    bool acteurs::operator == (const acteurs & act)
    {
        return nom == act.nom && prenom == act.prenom;
    }
    friend ostream & operator << (ostream & os, const acteurs & act)
    {
        cout<<act.nom<<" "<<act.prenom;
        return os;
    }
     
    friend istream & operator >> (istream & is, const acteurs & act)
    {
        chaine n;
        chaine p;
        is>>n>>p;
        acteurs act2(n, p);    
        act = act2;
        return is;
    }
    je sais pas si vous pouvez m'apporter quelques remarques ou idées.
    desole pour ce long code et merci beaucoup.
    Faites une recherche sur le forum et/ou sur internet et lisez la doc officielle avant de poser une question svp.
    et n'oubliez pas de lire les FAQ !
    FAQ Java et les cours et tutoriels Java
    Doc JAVA officielle
    AngularJS 1.x
    Angular 2

    Do it simple... and RTFM !

  2. #2
    Membre averti
    Inscrit en
    Mai 2004
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 15
    Par défaut
    Heu, juste un éclaircissement...

    je suis en train de coder un projet de gestion d'une videotheque. et j'aimerais avoir votre aide pour quelque chose.
    je sais pas si vous pouvez m'apporter quelques remarques ou idées.
    L'aide en question que tu recherches, c'est te donner une remarque sur ton code? Ou des idées sur quoi?

  3. #3
    Membre émérite Avatar de slim
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2002
    Messages
    938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2002
    Messages : 938
    Par défaut
    Citation Envoyé par SauCisS
    L'aide en question que tu recherches, c'est te donner une remarque sur ton code? Ou des idées sur quoi?
    des remarques sur mon code, et comme, j'en suis sur, il y a pas mal de choses a corriger, des idées pour que je puisse l'améliorer...

    remarque : j'ai créé une classe chaine pour pouvoir l'utiliser comme type.
    exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     private :
                       chaine nom;
    merci
    Faites une recherche sur le forum et/ou sur internet et lisez la doc officielle avant de poser une question svp.
    et n'oubliez pas de lire les FAQ !
    FAQ Java et les cours et tutoriels Java
    Doc JAVA officielle
    AngularJS 1.x
    Angular 2

    Do it simple... and RTFM !

  4. #4
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Quelques remarques sur ton code :

    - Remplace donc ta classe chaine par std::string, c'est fait pour (voir la FAQ pour + de détails).

    - Tes constructeurs par copie et opérateurs d'affectation sont inutiles, la version générée par le compilo marchera très bien dans le cas de tes classes. Et fais bien attention au type de retour de ton opérateur = (ça doit être une référence). D'ailleurs tu oublies de renvoyer *this, le compilo ne dit rien ?

    - N'oublie pas de prendre les gros paramètres (chaine) par référence constante.

    - L'utilité de fournir un accès complet en lecture / ecriture via des accesseurs pour les données membres privées est souvent discuté. En général mieux vaut mettre directement celles-ci en accès public (voir la FAQ là aussi). Mais surtout, as-tu réellement besoin d'"un accès complet sur chaque donnée membre de tes classes ?

    Pour ce qui est de l'organisation des classes je n'ai pas trop regardé en détail, mais il me semble que le lien de composition entre Film et Acteur est incorrect. Là tu vas avoir un même acteur dupliqué dans chaque film qu'il aura fait. J'aurais plutôt vu un lien de type pointeur / référence vers une instance unique pour chaque acteur. Ainsi tu éviteras les incohérences qui peuvent être induites par ce genre de redondance.

  5. #5
    Membre émérite Avatar de slim
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2002
    Messages
    938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2002
    Messages : 938
    Par défaut
    Citation Envoyé par Loulou24
    - Remplace donc ta classe chaine par std::string, c'est fait pour (voir la FAQ pour + de détails).
    je suis boligé de l'utiliser. c'est un projet que je dois presenter a l'oral, et c'est imposé. En fait, c'est pour savoir utiliser les liens de composition (par exemple pour le constructeur etc.)

    Citation Envoyé par Loulou24
    - Tes constructeurs par copie et opérateurs d'affectation sont inutiles, la version générée par le compilo marchera très bien dans le cas de tes classes. Et fais bien attention au type de retour de ton opérateur = (ça doit être une référence). D'ailleurs tu oublies de renvoyer *this, le compilo ne dit rien ?
    - pour les constructeurs par copie et opérateurs d'affectation, je crois que je suis un peu obligé. dans chaque classe présente dans mon cours, on retrouve les constructeurs etc. la structure de la classe est quasiment la meme a chaque fois.

    - Pourquoi dans le cas de mes classes ca marche tres bien ?

    - c'est bon pour le type de retour et le "return *this;". C'est clair j'avais oublié.

    Citation Envoyé par Loulou24
    - N'oublie pas de prendre les gros paramètres (chaine) par référence constante.
    - est ce que je dois le faire (const chaine & variable) a chaque fois que j'ai une variable de type chaine en parametre ?

    Citation Envoyé par Loulou24
    - L'utilité de fournir un accès complet en lecture / ecriture via des accesseurs pour les données membres privées est souvent discuté. En général mieux vaut mettre directement celles-ci en accès public (voir la FAQ là aussi). Mais surtout, as-tu réellement besoin d'"un accès complet sur chaque donnée membre de tes classes ?
    euh... non pas vraiment, en verité je mets toujours les accesseurs et le mutateurs au cas ou. Vu que dans le cours (je reparle du cours )c'est comme ca.

    Citation Envoyé par Loulou24
    Pour ce qui est de l'organisation des classes je n'ai pas trop regardé en détail, mais il me semble que le lien de composition entre Film et Acteur est incorrect. Là tu vas avoir un même acteur dupliqué dans chaque film qu'il aura fait. J'aurais plutôt vu un lien de type pointeur / référence vers une instance unique pour chaque acteur. Ainsi tu éviteras les incohérences qui peuvent être induites par ce genre de redondance.
    là c'est un peu plus compliqué... je vais étudier ca et essayer de corriger par la suite.

    en tous cas, merci beaucoup.
    Faites une recherche sur le forum et/ou sur internet et lisez la doc officielle avant de poser une question svp.
    et n'oubliez pas de lire les FAQ !
    FAQ Java et les cours et tutoriels Java
    Doc JAVA officielle
    AngularJS 1.x
    Angular 2

    Do it simple... and RTFM !

  6. #6
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    - Pourquoi dans le cas de mes classes ca marche tres bien ?
    Parce que toutes tes données membres ont un constructeur par copie et un opérateur d'affectation qui font leur job. Ca n'aurait pas été le cas par exemple si tu avais une donnée membre de type pointeur brut, où il aurait fallu (dans la plupart des cas) copier l'objet pointé et non le pointeur. C'est en partie pour ceci qu'on englobe toujours nos ressources dans des objets automatiques : une fois que c'est fait on n'a plus à gérer tous ces aspects, et on peut se passer des destructeur / constructeur par défaut / par copie / opérateur d'affectation pour nos classes.

    - est ce que je dois le faire (const chaine & variable) a chaque fois que j'ai une variable de type chaine en parametre ?
    Oui, ça ne change rien ni au code appelant, ni à la fonction, et c'est plus performant que le passage par copie. Donc ne t'en prive pas.

    euh... non pas vraiment, en verité je mets toujours les accesseurs et le mutateurs au cas ou. Vu que dans le cours (je reparle du cours )c'est comme ca.
    Oui, si on codait comme nos professeurs on aurait déjà 1000 lignes de code pour chaque classe, en dehors du contenu "utile". Mais bon, si ça fait plaisir aux profs... Tu changeras ce genre de chose plus tard avec l'habitude.

    Par contre, autant je ne suis pas contre le fait de coder un setter et un getter pour une variable membre si c'est justifié, autant en mettre juste "au cas où" brise totalement les principes d'encapsulation. Toutes les variables membres ne sont pas faites pour être exposées publiquement, c'est un aspect important de la POO.

  7. #7
    Membre émérite Avatar de slim
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2002
    Messages
    938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2002
    Messages : 938
    Par défaut
    Bonjour,

    Citation Envoyé par Loulou24
    [...] il me semble que le lien de composition entre Film et Acteur est incorrect. Là tu vas avoir un même acteur dupliqué dans chaque film qu'il aura fait. J'aurais plutôt vu un lien de type pointeur / référence vers une instance unique pour chaque acteur. Ainsi tu éviteras les incohérences qui peuvent être induites par ce genre de redondance.
    pour le lien de type pointeur, je suis d'accord :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    class film : public video
    {
        private:
            chaine genre;
    	chaine realisateur;
    	acteurs * acteur;
    ...
    je dois mettre aussi le pointeur dans la classe "acteurs"
    et les references seront utilisées dans les fonctions membres, c'est bien ca ?
    Mais, le pointeur / reference unique vers chaque acteur, je crois pas parce que un film peut comporter plusieurs acteurs, et un acteur peut jouer dans plusieurs films. Je vois pas comment je pourrais faire...

    Merci beaucoup.
    et bonne journée
    Faites une recherche sur le forum et/ou sur internet et lisez la doc officielle avant de poser une question svp.
    et n'oubliez pas de lire les FAQ !
    FAQ Java et les cours et tutoriels Java
    Doc JAVA officielle
    AngularJS 1.x
    Angular 2

    Do it simple... and RTFM !

  8. #8
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    je dois mettre aussi le pointeur dans la classe "acteurs"
    et les references seront utilisées dans les fonctions membres, c'est bien ca ?
    Mais, le pointeur / reference unique vers chaque acteur, je crois pas parce que un film peut comporter plusieurs acteurs, et un acteur peut jouer dans plusieurs films. Je vois pas comment je pourrais faire...
    C'est pas très clair tout ça, j'ai l'impression que tu t'embrouilles un peu.

    Personnellement j'aurais vu une donnée membre de type tableau de pointeurs, du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    class film : public video
    {
    private :
     
        chaine genre;
        chaine realisateur;
        std::vector<acteurs*> acteurs;
    };

  9. #9
    Membre émérite Avatar de slim
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2002
    Messages
    938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2002
    Messages : 938
    Par défaut
    salut,

    j'ai pensé à un autre truc. Créer une classe "listacteurs" et l'utiliser comme type dans la classe "film" : (je prevois de creer les classes suivantes : "list", "element", et pour chaque classe ayant un lien de composition avec une autre classe, je crée une classe "listclasse", j'espere que je me fais comprendre. j'aurais en fait la classe )
    tout ca, parce que je crois que je dois pas utiliser la STL. je dois tout faire moi meme (comme la classe chaine, date etc. nb: je les ai toutes créé)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    class film : public video
    {
         private:
              chaine genre;
              chaine realisateur;
              listacteurs * acteurs;
    merci beaucoup... c'est sympa
    Faites une recherche sur le forum et/ou sur internet et lisez la doc officielle avant de poser une question svp.
    et n'oubliez pas de lire les FAQ !
    FAQ Java et les cours et tutoriels Java
    Doc JAVA officielle
    AngularJS 1.x
    Angular 2

    Do it simple... and RTFM !

Discussions similaires

  1. Réponses: 2
    Dernier message: 26/02/2012, 18h11
  2. modifier un lien d'heritage
    Par isma92 dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 07/07/2008, 10h07
  3. combinaison de la composition et l'heritage
    Par ammah dans le forum Diagrammes de Classes
    Réponses: 2
    Dernier message: 13/04/2008, 21h29
  4. [DC] le lien identifiant en UML : association / composition / aggrégation
    Par sly3333 dans le forum Diagrammes de Classes
    Réponses: 5
    Dernier message: 30/10/2007, 08h57
  5. Heritage et composition
    Par foufa007 dans le forum Diagrammes de Classes
    Réponses: 5
    Dernier message: 06/04/2007, 19h17

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