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 :

problème d'héritage en c++


Sujet :

C++

  1. #1
    Membre averti
    Inscrit en
    Novembre 2006
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 35
    Par défaut problème d'héritage en c++
    Bonjour à tous (bonsoir plutot )
    Voila j'ai un petit soucis dont je n'arrive pas à trouver la solution.

    Je suis actuellement en train de découvrir le c++ et viens de me lancer dans l'héritage.
    Jusque la tout ce passait à peu près normalement sauf que je n'arrive pas à acceder à une methode de ma classe mère.. Et je ne sais pas trop pourquoi..

    Voici le code :
    Je vous explique après ce qui cloche ..

    Main.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
     
    #include <cstdlib>
    #include <iostream>
    #include "personnes.h"
    #include "etudiants.h"
     
    using namespace std;
     
    int main(void)
    {
        int i = 1;
        Personnes fontm(i,"Font","Mic","contact@fontmic.truc");
        i++; // on incremente l'identifiant
        Personnes fontn(i,"Font","Nic","fontnic@yahoo.fr");
        i++; // on incremente l'identifiant
        fontm.getInfos();
        fontn.getInfos();
        cout << endl;
        cout << "** Changement de l'email fontn" << endl;
        cout << endl;
        fontn.setMail("fonfonnini@yahoo.fr");
        fontn.getInfos();
     
        // -- on va essayer maintenant de spécifier tout ça et de faire un étudiant :) 
     
        cout << endl;
        cout << "****************************" << endl;
        cout << "** Creation d'un Etudiant : " << endl;
        cout << "****************************" << endl;
        cout << endl;
     
        Etudiants gab(i,"La","Gab","ga@hotmail.fr",2006,false);
        i++; // on incremente l'identifiant
        gab.getInfos();
     
        // va laisser le temps à l'utilisateur de lire les informations et va attendre 
        // une action de sa part
        system("PAUSE");
        return EXIT_SUCCESS;
    }
    Personnes.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 _PERSONNES_H_
    #define _PERSONNES_H_
     
    class Personnes
    {
    	private : 
                int identifiant;
                char * nom, * prenom, * mail; // attention de bien mettre * devant chaque chaine
        public:
    		// constructeurs
    		Personnes(); // par defaut
    		Personnes(int &,char*,char*,char*); // par initialisation
    		Personnes(const Personnes &); // par copie
    		// destructeur
    		~Personnes();
    		// methodes de la classe
    		void getInfos(); // acceder aux informations de la personne
    		void setNom(char *); // changer son nom
    		void setPrenom(char *); // changer son prenom
    		void setMail(char *); // changer son mail
    		// notons que nous ne changerons pas son identifiant qui est unique
    };
     
    #endif
    Personnes.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
    65
    66
    67
    68
    69
    70
    71
    72
     
    #include <iostream>
    #include "personnes.h" 
     
    using namespace std;
     
    // ****************************************************************************
    // *********** debut de la déclaration des constructeurs destructeur **********
    // **************************************************************************** 
     
    // constructeur par defaut
    Personnes::Personnes()
    {
    	identifiant = 1;
    	nom = "defaut";
    	prenom = "defaut";
    	mail = "defaut@defaut.fr";
    }
     
    // constructeur par initialisation
    Personnes::Personnes(int & ident, char * name, char * firstname, char * courriel)
    {
        identifiant = ident;
        nom = name;
        prenom = firstname;
        mail = courriel;                         
    }
     
    // constructeur par copie
    Personnes::Personnes(const Personnes & pers)
    {
        identifiant = pers.identifiant;
        nom = pers.nom;
        prenom = pers.prenom;
        mail = pers.mail;                          
    }
     
    // destructeur
    Personnes::~Personnes()
    {
    }
     
    // ***************************************************************************
    // *********** debut de la déclaration des methodes **************************
    // ***************************************************************************
     
    // permettra l'affichage des informations des personnes
    void Personnes::getInfos()
    {
         cout << " ---------------------------------------------------------- " << endl;
         cout << " -- Informations relatives a :" << nom << " " << prenom << endl;
         cout << " -- Identifiant : " << identifiant << endl;
         cout << " -- Mail : " << mail << endl;      
    } 
     
    // permettra la modification du nom de la personne
    void Personnes::setNom(char * newname)
    {
         nom = newname;     
    }
     
    // permettra la modification du prenom de la personne
    void Personnes::setPrenom(char * newpren)
    {
         prenom = newpren;     
    }
     
    // permettra la modification du mail de la personne
    void Personnes::setMail(char * newmail)
    {
         mail = newmail;     
    }
    Etudiants.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
     
    #ifndef _ETUDIANTS_H_
    #define _ETUDIANTS_H_
     
    #include "personnes.h" // fichier d'entete herite
     
    class Etudiants : public Personnes
    {
        private :   
                int promotion;
                bool boursier;
                char * vraifaux;
     
                // tableau de float contenant les notes
     
    	public:
    		// constructeurs
    		Etudiants(); // par defaut
    		Etudiants(int &,char*,char*,char*,int,bool); // constructeur par initialisation
    		Etudiants(const Etudiants &); // constructeur par defaut
    		~Etudiants(); // destructeur
     
    		void getInfos(); // accès aux nouvelles informations ainsi qu'aux précédentes
    		void setBourses(bool); // modification des bourses
    		void addNotes(int,float); // ajout de notes
    };
     
    #endif // _ETUDIANTS_H_
    Et enfin Etudiants.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
     
    #include <iostream>
    #include "etudiants.h"
    #include "personnes.h"
     
    using namespace std;
     
    // *********************************************************************
    // *********** Déclaration des constructeurs et destructeurs ***********
    // *********************************************************************
     
    // constructeur par défault
    Etudiants::Etudiants()
    {
    	Personnes(); // création d'une personne vide
        promotion = 2006; // complement d'informations
        boursier = false; // complement	d'informations
    }
     
    // constructeur par initialisation
    Etudiants::Etudiants(int & ident, char * name, char * firstname, char * email, int promo, bool bours)
    {
        Personnes(ident,name,firstname,email);
        promotion = promo;
        boursier = bours;                         
    }
     
    // constructeur par copie
    Etudiants::Etudiants(const Etudiants & e)
    {
        Personnes((Personnes) e);
        promotion = e.promotion;
        boursier = e.boursier;                       
    }
     
    // destructeur
    Etudiants::~Etudiants(){}
     
    // *********************************************************************
    // *********** Déclaration des méthodes diverses à la classe ***********
    // *********************************************************************
    void Etudiants::getInfos()
    {
         // test pour l'affichage en texte du status de boursier ou non
         if(boursier == false)
         {
                 vraifaux = "non";                
         }
         else
         {
                 vraifaux = "oui";     
         }
        this->Personnes::getInfos(); // accède normalement aux informations de la personne
        cout << " -- Promotion : " << promotion << endl; // affichage supplémentaire 
        cout << " -- boursier ? : " << vraifaux << endl; // affichage supplémentaire                
    }
    |
    |
    \ /

    Pour résumer
    Tout ce passe dans cette petite méthode
    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
     
    void Etudiants::getInfos()
    {
         // test pour l'affichage en texte du status de boursier ou non
         if(boursier == false)
         {
                 vraifaux = "non";                
         }
         else
         {
                 vraifaux = "oui";     
         }
        this->Personnes::getInfos(); // accède normalement aux informations de la personne
        cout << " -- Promotion : " << promotion << endl; // affichage supplémentaire 
        cout << " -- boursier ? : " << vraifaux << endl; // affichage supplémentaire                
    }
    Comme vous pouvez le voir dans le main je créer un nouvel étudiant avec certaines informations.
    Par la suite je construis une nouvelle personne avec ces mêmes informations, et je complete avec les informations de mon étudiants..
    J'aimerais afficher les info de la personne et les info complementaires.
    C'est ici que ça beugue, il m'affiche bien les info de la personne, mais prend les information du constructeur par défaut.
    En gros ça m'affiche ça


    ...
    blabla des autres trucs d'avant qui fonctionnent ...
    ...

    ----------------------------------------------------------
    -- Informations relatives a : defaut defaut
    -- Identifiant : 1
    -- Mail :defaut
    -- promotion : 2006
    -- boursier : non
    Comme vous pouvez le constater ce n'est pas ce que je recherche.
    La classe personne fonctionne correctement
    J'ai essayer avec et sans le this-> devant Personnes::getInfos() de mon GetInfos d'Etudiants.
    Savez vous pourquoi cette drole de chose m'arrive t'elle?

    En vous remerciant d'avance j'espère que vous saurez m'indiquer une réponse.
    Merci..
    Bonne nuit à vous

  2. #2
    Membre averti
    Inscrit en
    Août 2006
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 16
    Par défaut
    as-tu essayé dans ta classe hérité de désactivé l'appel du constructeur de la classe personne ?

  3. #3
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 292
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 292
    Par défaut
    Hum... Reprends tranquillement le C++. Tu es passé à côté des bases. Ta gestion des chaines de caractères est complètement à l'ouest.
    Faisons simple et correct => utilise le type standard, à savoir std::string. Cf la FAQ ou un vrai cours pour débutants qui en parlera avant les char* (qui auraient dû être constants -- et l'int, pas une référence !).

    Pour ton problème. Appelles le constructeur d'initialisation de ta classe personne depuis la classe étudiant. Cela se fait dans la liste d'initialisation. Et nulle par ailleurs ; je précise au vu de ton constructeur de recopie qui ne fera rien de bon.
    Sans le recours à la liste d'initialisation, le constructeur par défaut est systématquement appelé. Ce que tu observes est normal. Pour esquiver ce genre de bourdes, j'ai tendance à ne jamais proposer de constructeur par défaut, et encore moins de mutateurs pour des données que l'on est à même de connaitre avant la construction. Le code est plus simple, plus compact, et permet de déclarer des données non mutables.


    Choses qu'il te faudra corriger -- pour le prochain chapitre j'imagine : ta fonction getInfo() devra être virtuelle, de même que le destructeur.

    Concernant le constructeur de recopie, chose que les cours oublient de préciser : c'est rarement compatible avec l'héritage public. Et de toutes façons rarement d'un grand intérêt quand on a une sémantique d'entité. La bonne façon de faire, ici, est:
    - l'opération d'affectation, déclaré privé, mais non défini
    - le constructeur de recopie protégé (si besoin de duplication avéré)
    - une fonction de clonage publique qui appelle le constructeur de recopie protégé (si besoin de duplication avéré)
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  4. #4
    Membre averti
    Inscrit en
    Novembre 2006
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 35
    Par défaut
    Bonjour bonjour
    Merci pour ces petites réponses et surtout toi Luc, c'est vraiment ce qui me fallait, un petit point explicatif sur mes principals défauts. Je t'en remercie

    En ce qui concerne mon majeur problème c'est bien la liste d'initialisation qu'il me fallais, en plus c'est drôle je les aient utilisées dans toutes mes autres petits programmes mais la je me suis dis, tiens ça fonctionnera pas ...
    Raté
    Merci encore

    Sinon en ce qui concerne de changer mes char * en String, j'ai été piocher un peu dans la FAQ pour voir les principales différences. C'est vrai qu'elles sont nombreuses mais j'ai eu une toute petite phrase qui m'a fais un peu peur et que je n'arrive pas à comprendre

    " Même en C++ on est parfois obligé d'utiliser des char *. "

    Ma question est simple .. quand?
    J'ai tout de même fais ma mutation de char * à string sans problèmes

    Enfin une derniere petite question, c'est bien la getInfos() dans la classe fille qui dois être virtuelle, ce du fait que la classe mère porte déjà une classe de ce nom et que c'est simplement un complément d'informations. Sachant que dés lors qu'une classe comporte une fonction virtuelle, elle doit rentre son destructeur virtuel, ce sera le destructeur d'Etudiants qui sera virtual lui aussi. C'est bien ça professeur ?

    En tout cas merci encore pour cette réponse

  5. #5
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 292
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 292
    Par défaut
    Citation Envoyé par micfont999
    (a-) Merci pour ces petites réponses et surtout toi Luc, c'est vraiment ce qui me fallait, un petit point explicatif sur mes principals défauts. Je t'en remercie

    (b-) Sinon en ce qui concerne de changer mes char * en String, j'ai été piocher un peu dans la FAQ pour voir les principales différences. C'est vrai qu'elles sont nombreuses mais j'ai eu une toute petite phrase qui m'a fais un peu peur et que je n'arrive pas à comprendre

    " Même en C++ on est parfois obligé d'utiliser des char *. "

    Ma question est simple .. quand?
    J'ai tout de même fais ma mutation de char * à string sans problèmes

    (c-) Enfin une derniere petite question, c'est bien la getInfos() dans la classe fille qui dois être virtuelle, ce du fait que la classe mère porte déjà une classe de ce nom et que c'est simplement un complément d'informations.

    (d-) Sachant que dés lors qu'une classe comporte une fonction virtuelle, elle doit rentre son destructeur virtuel, ce sera le destructeur d'Etudiants qui sera virtual lui aussi. C'est bien ça professeur ?
    a- Avec plaisir.

    b-
    * Essentiellement quand on a besoin de dialoguer avec une API à la C non const-correcte.

    * Et aussi, quand on a du code existant sur lequel on doit se greffer qui va nous poser des problèmes avec des string (car il voudra faire des malloc/new/XMLString::alloc ; car il s'attendra à ce que l'on fasse des free/delete[]/XMLSting::release ; ...) Chose qui n'empêche pas d'utiliser du char* au niveau de l'interface, mais du std::string en interne.

    * De temps à temps on veut bidouiller au plus proche de la machine (si je puis dire), ou optimiser certains points pour proposer des alternatives plus efficaces à std::string dans des contextes bien définis. Les char* sont les trucs de plus bas niveau qui sont au coeur de ces classes de chaînes de caractères.
    Quand on part dans cette direction, on essaie de faire en sorte que quelqu'un qui a une maitrise suffisante le langage étende la bibliothèque du projet, tandis que les autres développeurs utilisent sans avoir à rentrer dans les détails.

    c- En C++, une fonction virtuelle doit être connue pour être virtuelle dès sa première déclaration : dans la classe mère.

    d- C'est une bonne première approximation. (Il y a des cas, que tu auras tout le temps de voir plus tard, où le destructeur est protégé et non virtuel -- Mais ce n'est absolument pas le cas des classes que tu nous as montré)
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  6. #6
    Membre confirmé Avatar de b Oo
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 179
    Par défaut
    Salut,
    pour les char *, je dirais quand tu as besoin de meilleurs performances (mais bon la c'est vraiment si tu développes quelque chose ou le temps d'execution est primordial).

    Pour la fonction virtuelle, c'est dans la classe MERE !
    En fait une classe fille c'est juste une spécialisation de la classe mere.
    En déclarant getInfo virtuelle dans la classe Mere, tu peux la redéfinir dans les classes filles (ou non, suivant les cas).
    Donc après si tu es sur une classe fille, la methode getInfo de la classe fille sera appelé (si elle a été redéfinie, sinon c'est celle de la classe mère).

    Il faut savoir que quand tu hérites, la classe fille hérite aussi des fonctions (public et protected). Donc ici tu as deux getInfos dans la classe etudiants : celle de la classe mere et celle de la classe etudiant.

    De plus dès que tu as une fonction virtuelle, il te faut un destructeur virtuel aussi. Voir la FAQ C++

    EDIT: grillé

  7. #7
    Membre averti
    Inscrit en
    Novembre 2006
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 35
    Par défaut
    Et bin j'en est appris plus en trois messages sur un forum, qu'en 3 mois de cours à la fac mdr.
    Pourtant je suit les cours et je suis attentif, mais faut croire que vous avez une façon bien plus simple et compréhensible pour expliquer
    Merci encore à vous deux, très franchement vous m'avez bien aidé et j'ai pu comprendre certains trucs que je n'arrivais pas trop à piger

    Merci à vous deux, encore une fois
    Dommage qu'on ne puisse pas vous mettre des petites notes à chaque fois que vous aidez quelqu'un ^^
    Système à prévoir ça

    Bon je m'attaque à faire une petite classe friend de sondage des étudiants pour voir comment ça marche cte bebete, une ou deux surcharge d'opérateurs pour me mettre dans le bain, et après je m'en va retourner à mon php5 lol

    Merci à vous encore une fois, ça fais plaisir de voir que l'on peux tomber sur des personnes qui nous explique tranquillement les choses et qui ne vous disent pas, google est ton amis

    Et pi the suis un bon élève lol

    Merci encore

  8. #8
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    La fac leur spécialité c'est pas vraiment la programmation, mais plutôt des domaines théoriques spécifiques.
    Faut pas trop en demander des profs qui s'occupent du cycle licence.

  9. #9
    Membre averti
    Inscrit en
    Novembre 2006
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 35
    Par défaut
    Bien sur je ne dis pas le contraire,
    mais ça me choque un peu..
    J'ai deux DUT, un en prog pure, l'autre en imagerie et programmation.
    J'arrive en 3eme année de licence, je me dis, tiens on va apprendre des news trucs super
    Au fnal oui j'apprend un nouveau langage, mais c'est super mal expliqué, les profs ce refile des cours pleins de fautes ..
    Quand l'autre il te dis qu'il existe pas de booleens en C++ t'a de quoi te poser des questions

    Sinon j'ai un autre soucis
    J'ai créer ma classe amie, avec une méthode moyenne, pgcd et pleins d'autres petites machines pratiques dans la vie de tous les jours (bah oui je me lève, je me fais le pgcd de mes heures de cours converties en rationnels )
    Bref, j'ai fais appel à ma fonction friend

    dans Etudiants.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    class Etudiants : public Personnes
    {
        // nous allons faire appel à une classe amie pour pouvoir calculer la moyenne de l'élève
        // ultérieurement :)
        friend float fonctionsinc::moyenne(std::vector<float>);  
     
        private :   
                int promotion;
                bool boursier;
     
    ... blabla etc
    Voili ma classe fonctionsinc.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
     
    #ifndef _FONCTIONSINC_H_
    #define _FONCTIONSINC_H_
     
    // cette classe représente un ensemble de méthodes réutilisables partout.
    // par exemple le pgcd, ou bien les moyennes pour des notes
    // cette classe est préférable en tant qu'amie d'autres classes par exemple =)
    class fonctionsinc
    {
          // déclaration de toutes les variables accéssibles par la suite
        private : 
                float varmoyenne;
                int varpgcd;
     
    	public:
    		/// déclaration des constructeurs :)
    		fonctionsinc();
    		fonctionsinc(const fonctionsinc &);
     
    		// déclaration du destructeur
    		~fonctionsinc();
     
    		// déclaration des méthodes
    		float moyenne(std::vector<float>); // attention ne pas oublier le std:: =)
    		int pgcd(int);
     
    };
     
    #endif // _FONCTIONSINC_H_
    et fonctioninc.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
     
    #include <iostream>
    #include <string>
    #include <vector>
    #include "fonctionsinc.h" 
     
    using namespace std;
     
    // ****************************************************************************
    // *********** debut de la déclaration des constructeurs destructeur **********
    // **************************************************************************** 
    // constructeur par defaut
    fonctionsinc::fonctionsinc()
    {
        varmoyenne = 0.0;
        varpgcd = 0;
    }
     
    // constructeur par copie
    //fontionc_inc::fontionc_inc(const fontionc_inc & fonfon)
    //{
    //     varmoyenne = fonfon.varmoyenne;
    //     varpgcd = fonfon.pgcd;
    //}
     
    // destructeur
    fonctionsinc::~fonctionsinc(){}
     
    // ****************************************************************************
    // *********** debut de la déclaration des méthodes de la classe :)  **********
    // **************************************************************************** 
    float fonctionsinc::moyenne( vector<float> paramnotes)
    {
          // déclaration des variables utiles
          int i;
          int j = 0;
          float total = 0;
     
          // parcours du vecteur
          for(i = 0; i<paramnotes.size(); i++)
          {
               total += paramnotes[i]; 
               j++;      
          }
     
          // calcul et renvoi de la moyenne
          return total/j;
    }
    Jusqu'ici ça fonctionne..
    Mais je n'arrive pas à effectuer la moyenne des notes que j'ai créer ..

    Main.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
     
     
    ... blabla avant
     
        // -- ajout de quelques notes
        cout << endl;
        cout << "** Ajout de notes pour l'Etudiant" << endl;
        cout << endl;
     
        // réservation de deux variables pour l'ajout de notes dynamique
        float noteseleve;
        bool boucle = true;
     
        // texte de commande pour indiquer comment sortir
        cout << " -- Entrez la note a inserer : -1 pour quitter le programme" << endl;
     
        // début de la boucle
        while(boucle == true)
        {
              cout << "Inserez la note : ";       
              cin >> noteseleve; // on prend l'entree standard 
              if(noteseleve != -1) // si l'on à pas rentré -1
              {
                  gaboss.addNotes(noteseleve); // on insère la note
              }
              else // sinon
              {
                  break; // on sort de la boucle
              }
        }
     
        // on affiche les informations après être sorti de la boucle
        gaboss.getInfos();
        cout << " ------------ Moyenne Générale : ";
     
        gaboss.moyenne(notes); // ça ça ne marche pas :(
    gaboss est mon étudiant..
    l'insertion des notes fonctionne correctement et met le tout dans un vecteur notes.
    C'est la dernière ligne qui ne fonctionne pas (même à moi ça me semble logique, moyenne étant une méthode d'une classe amie d'Etudiant, même pas déclarée dans le Etudiants.cpp juste dans le code .h en friend, et notes provient d'Etudiants.

    Est ce que quelqu'un pourrais me dire comment faire pour appeler la méthode moyenne, de ma classe amie fonctioninc , en lui passant en paramètre le vecteur de la classe Etudiants, tout ceci dans mon petit main
    Je cherche de mon coté sur le net mais la j'avou autant pour les strings, et les autres j'ai réussi à me dépatouiller, autant la

    Désolé de vous déranger

    Merci d'avance

  10. #10
    Membre averti
    Inscrit en
    Novembre 2006
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 35
    Par défaut
    oups chu con c'est dans fonctionsinc que je dois mettre le friend
    Bref çane change pas grand chose à ma question ^^

    Edit :
    J'ai changé quelques petites choses :
    Entre autre le main devient :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        gaboss.getInfos();
        cout << " ------------ Moyenne Générale : ";
        gaboss.moyenneamie();
    et après modification d'Etudiants.h Etudiants.cpp devient
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    float Etudiants::moyenneamie()
    {
          return fonctionsinc::moyenne(notes);      
    }
    c'est donc maintenant dans ma moyenneamie que je fais appel à moyenne de ma classe amie ...

    Sauf que j'ai une vieille erreur

    91 école\L3 MMI\POO\GestionEtudiants\etudiants.cpp cannot call member function `float fonctionsinc::moyenne(std::vector<float, std::allocator<float> >)' without object


  11. #11
    Membre confirmé Avatar de b Oo
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 179
    Par défaut
    Tu peux nous dire l'erreur qui se passe ?
    Déja il faut que tu mettes :
    friend float fonctionsinc::moyenne(std::vector<float>);
    en public et non en privée.

    Mais bon une fonction friend c'est juste qu'elle peut accéder au données privées de ton étudiant.
    Donc ici en admettant que tu es un vector notes dans ton etudiant.h, l'appelle a partir du main ne marchera jamais (notes, c'est quoi dans le main ?, un membre de Etudiants, si oui ca ne marchera pas).
    Je verrais plus un truc du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    float Etudiants::moyenne()
    {
      return fonctionsinc::moyenne(notes); // ou notes est le vector dans etudiant.h
    }
    Et le friend ne sert a rien ici (friend float fonctionsinc::moyenne(std::vector<float>); ).


    Exemple ou cela pourrait être utile (= 2ème méthode) :
    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
     
    class Etudiants
    {
      // ton code, on supose que notes est un vector de float
     
      public:
        friend float moyenne(const Etudiants & e);
    };
     
    float moyenne(const Etudiants & e)
    {
       float moyenne = 0.0;
       for(size_t i = 0; i < notes.size(); ++i) // size_t c'est un unsigned int
         moyenne += notes[i];
       return moyenne/static_cast<double> (notes.size()); // static_cast<type>(var) c'est juste pour transformer var en type
    }
    Code main.cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    // tu as un etudiant toto avec des notes
    toto.moyenne(); // renvoie la moyenne de toto avec la 1ere méthode
    moyenne(toto); // renvoie la moyenne de toto avec la 2eme méthode

  12. #12
    Membre averti
    Inscrit en
    Novembre 2006
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 35
    Par défaut
    Merci pour ta réponse b Oo
    J'ai une question qui va sembler plutot con mais elle m'intrigue depuis le début que je commence à étudier les friends.

    Je vois beaucoup de méthodes à l'arrache contenue dans aucune classe
    Dans ton exemple on vois bien que le float moyenne n'est pas contenu dans Etudiant.h
    Quel en est l'interet?
    Je ne comprend pas pourquoi on ne la met pas directement dans étudiant en fait..
    C'est surement con comme question mais je n'arrive pas trop à voir pourquoi on fait cela ..

    Merci encore de ta réponse

    Edit :
    En fait c'est encore pire que ça , c'est que je ne sais pas ou la mettre cette fonction moyenne en passant par le friend ..
    Pas dans le Etudiants.h, ni dans le Etudiant.cpp .. Donc ou ?
    Je crois que je commence à fatiguer lol, tite pause

    Edit2 : Notons que si je passe par la première méthode j'ai tjs la même érreur :
    cannot call member function `float fonctionsinc::moyenne(std::vector<float, std::allocator<float> >)' without object
    sur la ligne return fonctionsinc::moyenne(notes);

    Merci encore

  13. #13
    Membre confirmé Avatar de b Oo
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 179
    Par défaut
    L'intérêt de ne pas mettre moyenne dans ta classe ?
    Tu pourrais mettre moyenne dans ta classe mais vu que tu peux la calculer ce n'est pas obligé.
    Imaginons que tu stockes la moyenne. Comment tu vas faire pour la recupérer ? Tu fais un getMoyenne() ou un truc du même style.
    Ensuite tu fais un addNote, il faut recalculer la moyenne.

    Si tu ne la stocke pas, tu es obligé de recalculer la moyenne a chaque fois que tu appelles la méthode.

    Donc on va dire que si tu peux déduire la valeur en fonction des données que tu as déjà tu n'es pas obligé de stocker.

    Sinon le nom de l'étudiant tu dois le stocker, et là tu vois bien pourquoi (tu ne vas redemander le nom a chaque fois).

    Pourquoi l'appel de fonctionne pas ?
    Il faut savoir que les fonctions membres sont en fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class Toto
    {
       public:
         void setNom(const string & nom); // en fait il faut le voir comme void setNom(Toto & this, const string & nom);
         friend setNom(const string & nom); // en fait il faut le voir comme void setNom(const string & nom); donc ca ne marchera pas car tu n'as pas l'objet
    };
    C'est pour ça qu'il te demande un objet dans l'erreur.
    Si tu la déclares friend cela fonctionnera.

  14. #14
    Membre averti
    Inscrit en
    Novembre 2006
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 35
    Par défaut
    ça fais une heure que j'essai mais rien n'y fais, soit j'ai pas l'objet, soit la méthode n'est pas une fonction membre, il me trouve toujours quelque chose..

    J'abandonne, les friends ne sont pas mes amis pour ce soir lol.
    Nouvelle aventure demain ..
    Merci encore pour toute votre aide, encore une fois merci.

Discussions similaires

  1. [C#] Problème d'héritage, aide svp :(
    Par choas dans le forum Windows Forms
    Réponses: 12
    Dernier message: 06/05/2006, 11h46
  2. problème constructeur + héritage
    Par BOLARD dans le forum C++
    Réponses: 10
    Dernier message: 13/04/2006, 08h11
  3. [AS2] Problème d'héritage
    Par wwave dans le forum ActionScript 1 & ActionScript 2
    Réponses: 2
    Dernier message: 27/01/2006, 09h26
  4. Problème d'héritage ?
    Par Romanops dans le forum WinDev
    Réponses: 2
    Dernier message: 16/11/2005, 17h18
  5. Problème d'héritage d'une méthode protégée
    Par shenron666 dans le forum C++
    Réponses: 9
    Dernier message: 28/04/2005, 23h17

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