Creer objet avec classe heritée

Signaler
Messages postés
52
Date d'inscription
samedi 20 octobre 2007
Statut
Membre
Dernière intervention
7 mars 2010
-
Messages postés
3833
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
11 juin 2021
-
Bonjour à tous,
Voici mon problème : j'ai une classe personne et 2 classe dérivées
interne et externe mais je veut créer dans mon main une personne mais
je ne sais pas encore de quel type elle appartient :

Dans le main :
 switch(Option)
     {
     case 1 :   pEle = new personne;     //Impossible de créer (normal il y a une méthode abstraite ...)
                pEle->Saisir();                //Dans cette méthode je choisi le type de personne
                Entreprise.Ajouter(pEle);
     break;

Differentes classes :
 class personne
    {
    protected:
    char Nom[10+1];
    char Prenom[10+1];
    char Matricule[10+1];
            int prix;
        int Fax;
    public:
    personne(char*No="", char*Pre="", char *Mat="");

    void Affiche();
    void Saisir();

    virtual int GetSalaire() const = 0;

     personne*pSuivant; // pointeur vers l'objet suivant

     class Externe : public personne
{
    public:
        Externe(int p) {Fax = p;}

        int GetSalaire() const
          {
            int sal = 2500;
            return sal;
        }

    protected:
        int Fax;
};

class Interne : public personne
{
    public:
        Interne(int p) {prix = p;}

            int GetSalaire() const
          {
            int sal = 1200;
            return sal;
        }

    protected:
        int prix;
};

35 réponses

Messages postés
3833
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
11 juin 2021
122
Ce n'est pas possible. Ton code est mal pensé. Je te conseil le design pattern Factory qui répondra à ton problème.
En gros, il te faut une méthode qui retourne une instanciation de la bonne classe.

Petite exemple:
Personne* choice(int i)
{
    switch(i)
    {
     case 1:
        return new Interne;
     case 2:
        return new Externe;
    }
}

pEle = choice(1 ou 2, etc...);

De plus, évite les char truc[]; au profit de std::string truc;
Messages postés
52
Date d'inscription
samedi 20 octobre 2007
Statut
Membre
Dernière intervention
7 mars 2010

J'ai deja fait ça dans la methode saisir mais il faudrait que je mette ce code ailleur mais je ne voit pas ou
le code :
 void personne::Saisir()
     {
     int choix;
     personne*pEle;

    cout<<"\n\n\tVous etes externe a l'entreprise, taper 1";
    cout<<"\n\tVous etes interne a l'entreprise, taper 2";
    cout<<"\n\nVotre choix : ";
    cin>>choix;

    switch(choix)
    {
        case 1:
            cout<<"\nFax : ";
            cin>>Fax;
            pEle = new Externe(Fax);
        break;

        case 2:
            cout<< "\nMatricule :";
            cin>>prix;
            pEle = new Interne(prix);
          break;

        default : 
            cout<<"\nFax : ";
             cin>>Fax;
             pEle = new Externe(Fax);
          break;
    }
Messages postés
3833
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
11 juin 2021
122
C'est pas compliqué, la méthode saisir() doit être en dehors de la classe Personne, ou en statique.

Pour le cas statique, ton main donnerais ceci:
Dans le main :
   personne* pEle;
   pEle = personne::Saisir();
   Entreprise.Ajouter(pEle);
Messages postés
52
Date d'inscription
samedi 20 octobre 2007
Statut
Membre
Dernière intervention
7 mars 2010

J'ai déclaré la méthode Saisir() en statique comme ceci :
Dans la classe personne :    
                   static void Saisir();
et la méthode :
    static void Saisir()
     {...}

Et j'ai mis le code du main que tu ma donné.
Mais j'ai une erreur :
error: void value not ignored as it ought to be
Les propriétés Nom, Prénom,... ne sont pas reconnus il faut que je les déclarent public ou bien que je les re-déclare dans la méthode saisir()?
Messages postés
3833
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
11 juin 2021
122
C'est normal, une méthode statique ne peut accéder aux attributs d'une classe, vu qu'elle n'est relié à aucune instance de classe.
La méthode saisir n'a de toute façon pas besoin de toucher aux attributs privées.

Ton premier problème reste que ton code est mal pensé.

Si tu veux créer une personne, alors le mieux est de créer celle-ci et ses attributs en même temps. Pour cela, une des solutions possibles:

class Interne : public Personne
{
  public:
   Interne (int p, char*No="", char*Pre="", char *Mat="")
     : Personne(No, Pre, Mat), prix(p)
  {
  }
    protected:
        int prix;
};

void Saisir()
{
     int choix;
     personne*pEle;

    cout<<"\n\n\tVous etes externe a l'entreprise, taper 1";
    cout<<"\n\tVous etes interne a l'entreprise, taper 2";
    cout<<"\n\nVotre choix : ";
    cin>>choix;

    switch(choix)
    {
        case 1:
            cout<<"\nFax : ";
            cin>>Fax;
            pEle = new Interne( Fax, "nom", "prenom", "mat");
        break;

       [...]
}
Messages postés
52
Date d'inscription
samedi 20 octobre 2007
Statut
Membre
Dernière intervention
7 mars 2010

J'ai mis en place ton code mais j'ai encore l'erreur concernant les propriétés protected car elles sont utilisées quand je crée un new Interne par exemple :
                    pEle = new Interne( Fax, "", "prenommat");
Je doit egalement modifier mon constructeur mais je ne sais pas s'il faut que je mette les deux propriétés (prix et fax)?
Il est comme ceci pour l'instant :
                 Eleve::Eleve(char *No, char *Pre, char *Mat)
Merci d'avance.
Messages postés
3833
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
11 juin 2021
122
Je ne sais pas. Je ne peux pas deviner ce qui ne peut l'être. Qu'est-ce que "Eleve" ?
Messages postés
52
Date d'inscription
samedi 20 octobre 2007
Statut
Membre
Dernière intervention
7 mars 2010

Eleve est une classe :
    class Eleve
    {
    protected:
        char Nom[10+1];
        char Prenom[10+1];
        char Matricule[10+1];
        int prix;
        int Fax;

    public:
        Eleve(char*No="", char*Pre="", char *Mat="");

        void Affiche();
        void Saisir();
        virtual int GetSalaire() const = 0;
   }
Messages postés
52
Date d'inscription
samedi 20 octobre 2007
Statut
Membre
Dernière intervention
7 mars 2010

Eleve est personne est la meme classe je l'ai changé de nom
Messages postés
3833
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
11 juin 2021
122
Tes classes devraient ressembler à ceci:

#include

class Eleve
{
protected:
  std::string _nom;
  std::string _prenom;
  std::string _matricule;

public:
  Eleve(const std::string& nom, const std::string& prenom, const std::string& matricule);
  virtual void affiche() const;
  virtual int getSalaire() const = 0;
};

Eleve::Eleve(const std::string& nom, const std::string& prenom, const std::string& matricule)
  : _nom(nom), _prenom(prenom), _matricule(matricule)
{
}

void Eleve::affiche() const
{
  std::cout << _nom << std::endl;
  std::cout << _prenom << std::endl;
  std::cout << _matricule << std::endl;
}

class Interne : public Eleve
{
protected:
  int _prix;

public:
  Interne(const std::string& nom, const std::string& prenom, const std::string& matricule, int prix);
  virtual void affiche() const;
  virtual int getSalaire() const;
};

Interne::Interne(const std::string& nom, const std::string& prenom, const std::string& matricule, int prix)
  : Eleve(nom, prenom, matricule), _prix(prix)
{
}

void Interne::affiche() const
{
  Eleve::affiche();
  std::cout << _prix << std::endl;
}

int Interne::getSalaire() const
{
  return 1200;
}

class Externe : public Eleve
{
protected:
  int _fax;

public:
  Externe(const std::string& nom, const std::string& prenom, const std::string& matricule, int fax);
  virtual void affiche() const;
  virtual int getSalaire() const;
};

Externe::Externe(const std::string& nom, const std::string& prenom, const std::string& matricule, int fax)
  : Eleve(nom, prenom, matricule), _fax(fax)
{
}

void Externe::affiche() const
{
  Eleve::affiche();
  std::cout << _fax << std::endl;
}

int Externe::getSalaire() const
{
  return 2500;
}

int main()
{
  int choix;
  Eleve* pEle = 0;

  std::cout << "Vous etes externe a l'entreprise, taper 1" << std::endl
        << "Vous etes interne a l'entreprise, taper 2" << std::endl
        << "Votre choix : ";
  std::cin >> choix;

  int prix = 0;
  int fax = 0;
  switch (choix)
  {
    case 1:
      std::cout << "\nPrix : ";
      std::cin >> prix;
      pEle = new Externe("nom", "prenom", "matricule", prix);
      break;
    case 2:
      std::cout << "\nFax : ";
      std::cin >> fax;
      pEle = new Interne("nom", "prenom", "matricule", fax);
      break;
    default:
      std::cerr << "Erreur" << std::endl;
      return 1;
  }

  return 0;
}
Messages postés
52
Date d'inscription
samedi 20 octobre 2007
Statut
Membre
Dernière intervention
7 mars 2010

J'ai changé mon code mais je ne sais pas quoi mettre dans les constructeurs des classes filles (interne et externe) et j'ai une erreur lors de la creation du new Interne dans mon main() :

Mon code :

    #include
    #include <fstream.h> // pour declarer les 2 classes ostream et istream
    #include <string>
    #include <stdio.h>

    class Eleve
    {
    protected:
        std::string _nom;
        std::string _prenom;
        std::string _matricule;

    public:
        Eleve(const std::string& nom, const std::string& prenom, const std::string& matricule);
        virtual void Affiche() const;
        virtual int getSalaire() const = 0;
        virtual void Saisir();

     Eleve*pSuivant; // pointeur vers l'objet suivant

     friend ostream& operator<<(ostream& out,Eleve*v); // objet de type ostream pour ecrire
     //dans un fichier
     friend istream& operator>>(istream& in,Eleve*v);// objet de type istream pour lire un
     // fichier
     };

     class Ecole
     {
     private :
     Eleve*pPremier;
     Eleve*pCourant;
     public :
     Ecole();
     virtual ~Ecole();
     void Ajouter(Eleve *pEle);
     void AfficheTout();
     void Enregistrer();
     void Recuperer();
     };

     class Externe : public Eleve
{

protected:
  int _fax;

public:
  Externe(const std::string& nom, const std::string& prenom, const std::string& matricule, int fax);
  virtual void Affiche() const;
  virtual int getSalaire() const;
};

Externe::Externe(const std::string& nom, const std::string& prenom, const std::string& matricule, int fax)
  : Eleve(nom, prenom, matricule), _fax(fax)
{
}

void Externe::Affiche() const
{
  Eleve::Affiche();
  std::cout << _fax << std::endl;
}

int Externe::getSalaire() const
{
  return 2500;
}

class Interne : public Eleve
{
protected:
  int _prix;

public:
  Interne(const std::string& nom, const std::string& prenom, const std::string& matricule, int prix);
  virtual void Affiche() const;
  virtual int getSalaire() const;
};

Interne::Interne(const std::string& nom, const std::string& prenom, const std::string& matricule, int prix)
  : Eleve(nom, prenom, matricule), _prix(prix)
{
}

void Interne::Affiche() const
{
  Eleve::Affiche();
  std::cout << _prix << std::endl;
}

int Interne::getSalaire() const
{
  return 1200;
}

Eleve::Eleve(const std::string& nom, const std::string& prenom, const std::string& matricule)
  : _nom(nom), _prenom(prenom), _matricule(matricule)
     {
     pSuivant = NULL;
     }

void Eleve::Affiche() const
{
     // affiche le contenu avec alignement a gauche
     cout.setf(ios::left, ios::adjustfield);
     cout<< " Nom : ";
     // width permet de definir le nombre de caractere maxi
     cout.width(10);
     cout<<_nom;
     cout<< " Prenom : ";
     cout.width(10);
     cout<<_prenom;
     cout<< " Matricule : ";
     cout.width(10);
     cout<<_matricule;
     cout<<endl;
     }

     void Eleve::Saisir()
     {
     int choix;
     Eleve *pEle;

     cout<< " Nom : ";
          std::getline(std::cin, _nom);
    // cin.getline(_nom, sizeof(_nom) );
     cout<< " Prenom : ";
          std::getline(std::cin, _prenom);
   //  cin.getline(_prenom, sizeof(_prenom) );
     cout<< " Matricule : ";
          std::getline(std::cin, _matricule);
  //   cin.getline(_matricule, sizeof(_matricule) );
    }

     ostream& operator << (ostream& out, Eleve* v)
     {
     out<< v->_nom << ';';
     out<< v->_prenom << ';';
     out<< v->_matricule << ';';

     return out;
     }

     istream& operator >> (istream& in, Eleve* v)  // surcharge d'opertaeur
     {
  //   in.getline( v->_nom, sizeof(v->_nom),';' );
   //  in.getline( v->_prenom, sizeof(v->_prenom),';' );
  //   in.getline( v->_matricule, sizeof(v->_matricule),';' );

     return in;
     }

     Ecole::Ecole()
     {
     pPremier=NULL;
     pCourant=NULL;
     Recuperer();
     }

     void Ecole::Enregistrer()
     {
     //destrcution du fichier ECOLE.TXT
     remove("ECOLE.TXT");
     // ouverture en ecriture grace a la creation de l'objet ofstream
     ofstream Fichier("ECOLE.TXT");
     // test d'ouverture du fichier
     if (!Fichier) return;

     Eleve*pTemp;// pointeur vers l'objet Eleve
     pTemp=pPremier;

     // boucle qui permet de parcourir la liste chainee afin de sauvegarder chaque objet
     //de cette liste
     while(pTemp)
     {
     Fichier<< pTemp ;
     pTemp=pTemp->pSuivant;
     }
     }

     void Ecole::Recuperer()
     {
     //creation de l'objet ifstream pourlire le fichier
     ifstream Fichier("ECOLE.TXT");
     // test pour savoir si l'ouverture du fichier a reussi sinon on quitte la fonction
     if (!Fichier) return;

     Eleve *pTemp;
     }

     void Ecole::Ajouter(Eleve *pEle)
     {
     // condition si pointeur est sans valeur
     if (pPremier==NULL)
     {
     //initialisation des pointeurs grace a l'objet
     pPremier = pEle;
     pCourant = pEle;
     }
     else
     {
     pCourant->pSuivant = pEle;
     pCourant = pCourant->pSuivant;
     }
     }

     void Ecole::AfficheTout()
     {
     Eleve *pTemp;
     pTemp=pPremier;

     while(pTemp)
     {
     pTemp->Affiche();
     pTemp=pTemp->pSuivant;
     }
     }

     Ecole::~Ecole()
     {
     // appel de la fonction Enregistrer avant appel du destructeur
     Enregistrer();
     if (pPremier)
     delete pPremier;
     }

int main()
{
     // création d'un objet Cours de type Ecole
     Ecole Cours;
     // initialistion des pointeurs
     Eleve *pEle = 0;
     int Option = 0;
     int prix = 0;
     int fax = 0;
     int choix;

     // boucle pour le choix des options
     while (1)
     {
     cout<< "\nChoisissez une option de menu \n";
     cout<< "(1-Creation, 2-Afficher Ecole, 0-Pour quitter): ";
     //recuperation de votre choix
     cin>>Option;
     //annule le \n
     cin.ignore();

     switch(Option)
     {
     case 1 :
                std::cout << "Vous etes externe a l'entreprise, taper 1" << std::endl
                << "Vous etes interne a l'entreprise, taper 2" << std::endl
                    << "Votre choix : ";
                std::cin >> choix;

                  switch (choix)
                    {
                    case 1:
                    std::cout << "\nPrix : ";
                    std::cin >> prix;
                    pEle = new Externe(nom, prenom, matricule, prix);
                    break;
                    case 2:
                    std::cout << "\nFax : ";
                    std::cin >> fax;
                    pEle = new Interne(nom, prenom, matricule, fax);
                    break;
                    default:
                    std::cerr << "Erreur" << std::endl;
                    return 1;
                    }
                    pEle->Saisir();
                    Cours.Ajouter(pEle);
     break;

     case 2 : Cours.AfficheTout();
     break;

     case 0 : return 0;

     default : cout<< "\nChoix invalide\a\n";
     continue;
     }
     }
}
Messages postés
3833
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
11 juin 2021
122
J'ai apporté quelques corrections à ton code.
Quelques remarques:
- Utilise iostream et non iostream.h (qui est déprécié)
- Utilise std::getline, plutot que le cin.getline
- N'oublie pas que tu peux faire des getters/setters pour récupérer ou mettre à jour des attributs de classe. On ne les mets généralement pas en visibilité publique.
- Préfère std::endl à \n, qui est plus portable (je t'invite à jeter un coup d'oeil sur les problèmes et avantages de std::endl, et à regarder une implémentation de std::endl de mon cru, que j'avais nommé std::nl).

Fixe toi une norme d'écriture, voici la mienne, beaucoup basée sur celle de Sun, à titre indicatif:
  * Une classe porte une majuscule, un nom de variable ou un nom de fonction commence par une miniscule  (Utilisation du caml Case et du Pascal Case)
  * L'étoile ou l'esperluette, collé au type

A noter que je n'ai pas vérifier si ça fonctionnait, j'ai juste fait en sorte que ça compile.

#include
#include <fstream>
#include <string>

class Eleve
{
  friend std::ostream& operator<<(std::ostream& out, Eleve* v);
  friend std::istream& operator>>(std::istream& in, Eleve* v);

public:
  Eleve(const std::string& nom, const std::string& prenom, const std::string& matricule);

  virtual void affiche() const;
  virtual int getSalaire() const = 0;
  virtual Eleve* getSuivant() const;
  virtual void setSuivant(Eleve* suivant);
  virtual void print(std::ostream& o) const;

protected:
  std::string _nom;
  std::string _prenom;
  std::string _matricule;
  Eleve* _pSuivant;
};

class Ecole
{
public :
  Ecole();
  virtual ~Ecole();

  void ajouter(Eleve *pEle);
  void afficheTout();
  void enregistrer();
  void recuperer();

private :
  Eleve* _pPremier;
  Eleve* _pCourant;
};

class Externe : public Eleve
{
public:
  Externe(const std::string& nom, const std::string& prenom, const std::string& matricule, int fax);
  virtual void affiche() const;
  virtual int getSalaire() const;
protected:
  int _fax;
};

Externe::Externe(const std::string& nom, const std::string& prenom, const std::string& matricule, int fax)
  : Eleve(nom, prenom, matricule), _fax(fax)
{
}

void Externe::affiche() const
{
  Eleve::affiche();
  std::cout << _fax << std::endl;
}

int Externe::getSalaire() const
{
  return 2500;
}

class Interne : public Eleve
{
public:
  Interne(const std::string& nom, const std::string& prenom, const std::string& matricule, int prix);
  virtual void affiche() const;
  virtual int getSalaire() const;
protected:
  int _prix;
};

Interne::Interne(const std::string& nom, const std::string& prenom, const std::string& matricule, int prix)
  : Eleve(nom, prenom, matricule), _prix(prix)
{
}

void Interne::affiche() const
{
  Eleve::affiche();
  std::cout << _prix << std::endl;
}

int Interne::getSalaire() const
{
  return 1200;
}

Eleve::Eleve(const std::string& nom, const std::string& prenom, const std::string& matricule)
  : _nom(nom), _prenom(prenom), _matricule(matricule), _pSuivant(0)
{
}

Eleve* Eleve::getSuivant() const
{
  return _pSuivant;
}

void Eleve::setSuivant(Eleve* suivant)
{
  _pSuivant = suivant;
}

void Eleve::print(std::ostream& out) const
{
  out << _nom << ';';
  out << _prenom << ';';
  out << _matricule << ';';
}

void Eleve::affiche() const
{
  // affiche le contenu avec alignement a gauche
  std::cout.setf(std::ios::left, std::ios::adjustfield);
  std::cout << " Nom : ";
  // width permet de definir le nombre de caractere maxi
  std::cout.width(10);
  std::cout << _nom;
  std::cout << " Prenom : ";
  std::cout.width(10);
  std::cout << _prenom;
  std::cout << " Matricule : ";
  std::cout.width(10);
  std::cout << _matricule;
  std::cout << std::endl;
}

std::ostream& operator<< (std::ostream& out, Eleve* v)
{
  v->print(out);

  return out;
}

std::istream& operator>> (std::istream& in, Eleve* v)
{
  // Recuperation des donnees du Fichier
  // (voir fonction recuperer()) jusqu'au caractere ';'
  std::getline(in, v->_nom, ';');
  std::getline(in, v->_prenom, ';');
  std::getline(in, v->_matricule, ';');

  return in;
}

Ecole::Ecole()
  : _pPremier(0), _pCourant(0)
{
  recuperer();
}

void Ecole::enregistrer()
{
  //destrcution du fichier ECOLE.TXT
  remove("ECOLE.TXT");

  std::ofstream fichier("ECOLE.TXT");

  if (!fichier)
    return;

  Eleve* pTemp = 0;// pointeur vers l'objet Eleve
  pTemp = _pPremier;

  while (pTemp)
  {
    fichier << pTemp ;
    pTemp = pTemp->getSuivant();
  }
}

void Ecole::recuperer()
{
  std::ifstream fichier("ECOLE.TXT");

  if (!fichier)
    return;
}

void Ecole::ajouter(Eleve *pEle)
{
  if (_pPremier == 0)
  {
    //initialisation des pointeurs grace a l'objet
    _pPremier = pEle;
    _pCourant = pEle;
  }
  else
  {
    _pCourant->setSuivant(pEle);
    _pCourant = _pCourant->getSuivant();
  }
}

void Ecole::afficheTout()
{
  Eleve *pTemp;
  pTemp = _pPremier;

  while (pTemp)
  {
    pTemp->affiche();
    pTemp = pTemp->getSuivant();
  }
}

Ecole::~Ecole()
{
  enregistrer();
  // if (_pPremier) : Inutile car delete ne fait
  // automatiquement rien si _pPremier == 0
  delete _pPremier;
}

Eleve* saisirEleve()
{
  bool continuer = true;
  int choix;
  Eleve *pEle = 0;
  std::string nom;
  std::string prenom;
  std::string matricule;
  int prix = 0;
  int fax = 0;

  while (continuer)
  {
    std::cout << " Nom : ";
    std::getline(std::cin, nom);
    std::cout << std::endl << " Prenom : ";
    std::getline(std::cin, prenom);
    std::cout << std::endl << " Telephone : ";
    std::getline(std::cin, matricule);
    std::cout << "Vous etes externe a l'entreprise, taper 1" << std::endl
          << "Vous etes interne a l'entreprise, taper 2" << std::endl
          << "Votre choix : ";
    std::cin >> choix;

    switch (choix)
    {
      case 1:
    std::cout << std::endl << "Prix : ";
    std::cin >> prix;
    pEle = new Externe(nom, prenom, matricule, prix);
    continuer = false;
    break;
      case 2:
    std::cout << std::endl << "Fax : ";
    std::cin >> fax;
    pEle = new Interne(nom, prenom, matricule, fax);
    continuer = false;
    break;
      default:
    std::cerr << "Erreur choix invalide, recommencez" << std::endl;
    }
  }

  return pEle;
}

void menu()
{
  Ecole cours;
  int option = 0;
  bool continuer = true;

  while (continuer)
  {
    std::cout << "\nChoisissez une option de menu \n";
    std::cout << "(1-Creation, 2-Afficher Ecole, 0-Pour quitter): ";
    std::cin >> option;
    std::cin.ignore();

    switch (option)
    {
      case 1 :
    cours.ajouter(saisirEleve());
    break;
      case 2 :
    cours.afficheTout();
    break;
      case 0 :
    continuer = false;
    break;
      default :
    std::cerr << std::endl << "Choix invalide\a" << std::endl;
    }
  }
}

int main()
{
  menu();

  return 0;
}
Messages postés
52
Date d'inscription
samedi 20 octobre 2007
Statut
Membre
Dernière intervention
7 mars 2010

Merci de m'avoir arrangé mon code, je voudrais juste savoir si tu sais si la méthode GetType pourrais me permettre d'afficher dans mon fichier texte, soit le prix soit le fax, en fonction de ce qui est choisit.

PS : il ne me restera plus qu'a créer une fonction permettant de supprimer un Eleve :
J'ai fait une fonction et je voudrais avoir ton avis :

void Eleve::Supprimer(Eleve* pEle)
{
    *pPremier = *pEle;
    pCourant = NULL;
    char* Name = new char;

    ofstream Fichier("ECOLE.txt");

    if (Fichier.eof())
        cout << "La liste est vide!\n";
    else
    {
        cout << "Nom de l'eleve a supprimer: ";
        gets(Name);

        while (strcmp(pPremier->GetNom(),Name)!=0 && pPremier->GetNext() != NULL)
        {
            pCourant = pPremier;
            pPremier = pPremier->GetNext();
        }

        if (strcmp(pPremier->GetNom(),Name) == 0)
        {
            if (pCourant == NULL)
            {
                pPremier = (*pEle).GetNext();
                free(pEle);
                pEle = pPremier;
            }
            else
            {
                pCourant->SetNext(pPremier->GetNext());
                free(pPremier);
            }

            cout << "Fiche " << Name << " effac‚e avec succŠs!\n";
        }
        else
            cout << "\nErreur: Eleve" << Name << " non trouv,e!\n";
    }
}
Messages postés
3833
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
11 juin 2021
122
Pas besoin de "getType()".
Tu te fais une méthode getInformations en "virtual" dans Eleve qui retourne un const std::string& qui représente toutes les informations à mettre dans le fichier. Ensuite dans chacune des classe fille, tu retournes des choses en plus.
C'est le même principe que "affiche" sauf que ça n'écrit rien à l'écran, mais retourne une string qui contient tout.

Dans Ecole::enregistrer, tu remplaces ensuite:
fichier << pTemp ;
par
fichier << (pTemp->getInformations());

Je n'ai pas vérifier ta fonction supprimer, mais quelques petits trucs me dérangent:- pCourant NULL; // Ce n'est pas très gênant, mais en C++, on préfère écrire pCourant 0; Ce n'est pas très grave si tu mets = NULL.- char* Name new char; // En C++, on utilise des std::string, on ne s'amuse pas à faire des char* (sauf pour des cas vraiment très spécifique, ce qui n'est pas le cas ici)> std::string name;
- ofstream => std::ofstream
- cout => std::cout
- strcmp(pPremier->GetNom(),Name)!=0 => pPremier->GetNom() == Name
- free(pEle); => jamais de free ! Utilise delete !
Messages postés
52
Date d'inscription
samedi 20 octobre 2007
Statut
Membre
Dernière intervention
7 mars 2010

J'ai du mal comprendre mais j'ai fait ceci (désolé j'ai pas mal de lacunes):

void Externe::getInformations(const std::string&);
{
  Eleve::getInformations();
  return _fax;
}
Messages postés
3833
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
11 juin 2021
122
Effectivement, tu as de nombreuses lacunes. Il y a pas mal de chose que tu n'as pas compris. Il y a plein de chose qu'il faudrait que l'on te ré-explique, mais ce n'est pas le sujet de la question, contacte moi par mp, si tu veux en discuter.

getInformations renvoie un std::string, donc ce n'est pas void.
De plus, pour renvoyer des informations interne à une classe, pas besoin d'information supplémentaire, donc la méthode ne prendra rien en argument.

Pas testé:

const std::string& Externe::getInformations() const
{
   std::stringstream ss;
   ss << Eleve::getInformations() << " : " << _fax;
   return ss.str();
}
Messages postés
3833
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
11 juin 2021
122
>> J'ai mis dans la classe eleve la méthode suivante = 0 mais est ce que
j'ai
>> bon car comme cela retourne un string il faut peut être mettre =
NULL ?

>>
>>  virtual const std::string& Eleve::getInformations() const = 0;

La syntaxe "virtual type fonction() = 0", veut dire la méthode "type fonction()" sera abstraite. C'est à dire que la classe qui possède cette méthode, sera elle même abstraite, donc non instanciable. Les classes filles devront implémenter, c'est à dire posséder cette fonction, sous peine d'être elle même abstraite.Le "0" veut juste dire : abstrait. C'est bizarre, mais c'est comme cela, c'est la syntaxe du C++. Si tu met 1, ou = 2 ou = NULL, ça ne veut rien dire. Tu auras d'ailleurs l'erreur suivante: "erreur: invalid pure specifier (only `= 0' is allowed) before ‘;’ token"

Dans ton cas:
virtual const std::string& Eleve::getInformations() const = 0;

On va décortiquer cette écriture:
virtual : Signifie que la méthode peut être redéfinit correctement dans les classes filles.
const std::string& : retourne une chaîne de caractère, sans copier l'objet, mais qui ne sera pas modifiable. Equivaut à retourner std::string, mais en plus optimisé, puisqu'il n'y aura pas de copie inutile.
getInformations(): Nom de ta méthode.
const (mis après le nom d'une méthode): Veut dire que tu garanties que la méthode ne modifiera pas les attributs de la classe.
= 0: Combiné avec "virtual", spécifie que la méthode est "virtuelle pure".

Enfin il faut savoir que "NULL" équivaut strictement à "0". En C, on utilise NULL, mais en C++ on préfère utiliser 0.
De plus, std::string est une classe, et non un pointeur.
Messages postés
52
Date d'inscription
samedi 20 octobre 2007
Statut
Membre
Dernière intervention
7 mars 2010

J'ai une erreur sur la partie getInformations() :



const std::string& Eleve::getInformations() const
{
   std::stringstream ss;
   ss << _nom << " : " << _prenom << " : " << _matricule;
   return ss.str();
}

L'erreur qui apparait :

|In member function `virtual const std::string& Externe::getInformations() const':|
|warning: returning reference to temporary|

Est-ce que vous pourriez m'aider ?
Messages postés
3833
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
11 juin 2021
122
Remplace par:
std::string Eleve::getInformations() const
Messages postés
52
Date d'inscription
samedi 20 octobre 2007
Statut
Membre
Dernière intervention
7 mars 2010

Merci pour la réponse c'était bien ça.
Je ne peut pas récupérer les informations insérées dans le fichier texte car je pense qu'il faudrait que j'ajoute une partie dans chaque classe dérivée :

Actuellement :

std::istream& operator>> (std::istream& in, Eleve* v)
{
  std::getline(in, v->_nom, ':');
  std::getline(in, v->_prenom, ':');
  std::getline(in, v->_matricule, ':');
  return in;
}

Peut être qu'il faudrait quelque chose de ce style :

  std::getline(in, v->_prix, ':');  Dans la classe Interne, par exemple.

Pourrait tu m'aider a trouver comment je pourrait récupérer ces informations.