FIFO LIFO c++ Pile/file ??!! [Résolu]

zied9992000 9 Messages postés lundi 16 juillet 2007Date d'inscription 7 mars 2009 Dernière intervention - 27 déc. 2008 à 15:30 - Dernière réponse : cs_rt15 3982 Messages postés mardi 8 mars 2005Date d'inscription 7 novembre 2014 Dernière intervention
- 27 déc. 2008 à 23:44
slaut les amis, quelqu'un m'expliquer ou se trouve les fautes ici ??????? et merci beaucoup les amis ;)

#include

                        //Class Basepile  ##############################################
class basepile
{public:
int *p,taille;
public:
basepile(int);
basepile(const basepile&);
virtual void operator<(int);//empiler
virtual void operator>(int&);//depiler
friend ostream & operator<<(ostream &,const basepile &);
//ostream est la bib d'affichage
~basepile();
};
//__________________________________________________________________________________
//Definition des objets de Class  << Base pile >> -----------------
//___________________________________________________________________________________
basepile::basepile(int n=10)
{
     taille=n;
     p=new int[taille];
}

basepile::basepile(const basepile& bp)//constructeur par recopie
{taille=bp.taille;
     p=new int[taille];
     for (int i=0;i<taille;i++)
     *(p+i)=*(bp.p+i);
}

void basepile::operator<(int x)
{
     *p=x;
}

void basepile::operator>(int& x)
{
     x=*p;
}

ostream& operator<<(ostream & sortie,const basepile & b)
{
     for (int i=0;i(int&);
     friend ostream &operator<<(ostream &,const lifo &);
     ~lifo();
};
//___________________________________________________________________________________
//Definition des objets Class   << LIFO >> -----------------
//___________________________________________________________________________________

lifo::lifo(int n=10) :basepile(n)
{
 sommet=0;
}

lifo::lifo(lifo& l) //constructeur par recopie
{  sommet=l.sommet;
     taille=l.taille;
     p=new int[taille];
     for (int i=0;i<sommet;i++)
     *(p+i)=*(l.p+i);
}

 void lifo::operator<(int x) //empiler
{
     *(p+sommet)=x;
     sommet++;
}

void lifo::operator>(int& x) //dépiler
{  sommet--;
     x=*(p+sommet);
}

ostream& operator<<(ostream& sortie,lifo& l)
{
     for (int i=0;i<l.sommet;i++)
     sortie<<*(l.p+i);
      return(sortie);
}
                        //Class FIFO  ##################################################
class fifo:public basepile
{  public:
     int que,tete;
     public:
     fifo(int);
     fifo(fifo&);
     void operator<(int);
     void operator>(int&);
     friend ostream &operator<<(ostream&,const fifo&);
     ~fifo();
};

//___________________________________________________________________________________
//Definition des objets Classe   << FIFO >> -----------------
//___________________________________________________________________________________
fifo::fifo(int n=10):basepile(n)
{
 que=0; tete=0;
}

fifo::fifo(fifo& f)//constructeur par recopie
{  que=f.que;
     tete=f.tete;
     taille=f.taille;

     for (int i=tete;i<que;i++)
     *(p+i)=*(f.p+i);
}

 void fifo::operator<(int x) //empiler
{
     *(p+que)=x;
     que++;
}

void fifo::operator>(int& x) //dépiler
{
     x=*(p+tete);
     tete++;

}

ostream& operator<<(ostream& sortie,fifo& f)
{
     for (int i=f.tete;i<f.que;i++)
     sortie<<*(f.p+i);
      return(sortie);
}

//######################################################################################
             //---------------------Programme principale-----------------
//######################################################################################

void main()
{basepile *ptpile;
fifo fifo;
lifo lifo;
ptpile=&fifo;
*ptpile<0<1;
int i;
*ptpile>i;
cout<<"Pile= "<<*ptpile<<" i= " <(*ptpile,1);
cout<<"Pile= "<<*ptpile<<" i= " <
Afficher la suite 

4 réponses

Répondre au sujet
cs_rt15 3982 Messages postés mardi 8 mars 2005Date d'inscription 7 novembre 2014 Dernière intervention - 27 déc. 2008 à 23:30
+3
Utile
Salut,

Je sais pas si c'est la saison, mais il y a quand même un sacré paquet de demandes d'étudiants étrangers ces derniers temps. Je vais me reconvertir dans l'aide d'étudiant je sens. Dans l'étudiante ce serait encore mieux. Houla je m'égare.

Allons y. Pour voir si je peux me dépatoullier de cette horreur.

Compilation... Ca passe, mais pas avec les warnings. Les warnings, c'est le mal zied. Il faut compiler avec -Wall et tous les faire sauter. Parce que les (bons) profs ont un détecteur de warning intégré. Plus phylosophiquement, un compilo C++ laisse passé de telles horreurs qu'il faut au moins le régler pour qu'il fasse un peu gaffe.
In file included from C:/Program Files/CodeBlocks/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/backward/iostream.h:31,
                 from test.cpp:1:
C:/Program Files/CodeBlocks/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/backward/backward_warning.h:32:2: warning: #warning This file includes at least one deprecated or antiquate
d header. Please consider using one of the 32 headers found in section 17.4.1.2 of the C++ standard. Examples include substituting the <X> header for the <X.h> header for C++ includes, or i
nstead of the deprecated header . To disable this warning use -Wno-deprecated.
test.cpp:5: warning: `class basepile' has virtual functions but non-virtual destructor
test.cpp:55: warning: `class lifo' has virtual functions but non-virtual destructor
test.cpp:101: warning: `class fifo' has virtual functions but non-virtual destructor
test.cpp:154: error: `main' must return `int'
test.cpp:154: error: return type for `main' changed to `int'
test.cpp: In function `int main(...)':
test.cpp:158: error: void value not ignored as it ought to be
test.cpp:163: error: void value not ignored as it ought to be
test.cpp:166: error: `operator>' not defined
Après c'est plus ou moins facile de les enlever... Y en a qui sont particulièrement vicieux. Mais là, comme tu n'inclus pas de header suceptibles de poser problème, ça devrait bien se passer.

Le premier est fort simple : il te dit que iostream.h est une antiquité. Il faut utiliser iostream à la place.

Ensuite en C++, il y a les namespace. Comme son nom l'indique, c'est un espace de nom. En l'occurence, ici, tu vas utiliser ostream... Ces objets et classes sont définis dans le namespace std. Donc il faut que tu dises que tu vas utiliser ce namespace (using namespace std;), ou préfixer ces types.

Un facile : test.cpp:154: error: `main' must return `int'. Le main doit renvoyer le code d'erreur de l'application. Hop "int main" et un petit return 0 à la fin si tout s'est bien passé.

`class basepile' has virtual functions but non-virtual destructor

Quand on ne comprend pas un message d'erreur ou un warning, on le donne à google, et lui comprend.

Le compilateur ne peut pas savoir comment détruire une instance d'une classe enfant pointée comme une classe parente. Hum. Pas très clair mon explication.
Parent* p = new Child();
delete p;

Si le destructeur est pas virtuel, le delete p va utiliser le destructeur de Parent, et pas celui de Child.
Donc on met virtual devant le constructeur de basepile. Et on implémente des destructeurs de fifo et lifo.

 no matching function for call to `operator>(basepile&, int)'

Grand classique... Sur cette ligne :
operator>(*ptpile,1);

Alors là faudra m'expliquer cette ligne. Tu appelles une méthode comme si c'était une fonction. En lui passant en premier paramètre l'instance, comme c'est fait en interne pour les méthodes. Franchement, je me demande en quoi c'est compilé. Ou plutôt non, je veux pas le savoir. Et puis c'est comme si tu essayais de dépiler dans une constante... Hop, ça dégage.

: error: void value not ignored as it ought to be
*ptpile<0<1;

Hum. Bonne question. L'opérateur renvoie void. Ce void risque d'être traité lors du deuxième empilement je suppose... Si on fait renvoyer un int par <, on perd le message d'erreur. Mais pour plus de sûreté, je vais n'utilisé < qu'une fois par ligne.

Bien ! Cette fois ça compile avec un peu moins de chance de faire n'importe quoi.

Maintenant que le compilo est satisfait, passons à moi.
1) Je n'aime pas le code vaguement indenté. Les profs non plus en général.
2) Appelé des instances du nom de leurs classes... Original. Mais non mauvaise idée.
3) Les déclarations au milieu du code, c'est vrai que c'est tout à fait possible, mais ce n'est généralement pas apprécié.

Tu ne sens pas une vague redondance dans le code du main ? Nan ? Tu n'essaies pas faire deux tests identiques ? Le copier coller c'est mal. C'est la mort du programmeur. Jamais de copier coller. On fait une fonction test. Ce sera 5 fois plus lisible et 10 fois plus maintenable.

lilo et fifo héritent de basepile. Je trouve pas ce nom particulièrement bien choisi... En effet, une pile c'est LIFO. Ce sont les files (A ne pas confondre avec les filles) qui sont FIFO.

Ah, et on ne code pas en français. On code en anglais. Le code anglais est nettement plus compréhensible car il n'y a pas d'accent en anglais. Et cela rend le code, heu... universel. Tant pis pour les commentaire. De toute façon, qui commente, je vous le demande.

De même, c'est pas plus mal de se renseigner un peu sur les conventions de nommage d'un langage avant de s'en servir. En l'occurrence, en C++, on met des majuscules aux noms de classes.

Dans les classes mettre deux fois public:, c'est pas vraiment indispensable. Par contre, on met généralement les champs private. Ou protected si ils risquent d'être utilisés dans des classes filles. Si on a besoin d'y accèder, on met des accesseurs. Ca permet notamment de les mettre en lecture seule. Ca peut aussi beaucoup aider en cas de refactoring.

L'accès par pointeur *(p+i) est mignon, mais je préfère le p[i], plus soft.

programme principale ne prend pas de e à principale.

A part ça le code à l'air relativement correct.

Il reste un problème cependant. La "grosse erreur" du code.
Ici :
cout<<"Pile= "<<*ptpile;

L'opérateur appelé est celui de basepile... Bah vi, pourquoi en appelerait-il un autre ?

Pour contrer cela, on peut par exemple définir une méthode d'affichage virtuelle qui est appelé par un unique opérateur << définit dans la classe mère.

Voilà ce que ça me donne :
#include

using namespace std;

//Class DataStructure  ##############################################

class DataStructure
{
  protected:
    int* p;
    int size;
  public:
    DataStructure(int);
    DataStructure(const DataStructure&);
    virtual ~DataStructure();
    int getSize() const { return size; }
    int operator[](int index) const { return p[index]; }
    virtual void operator<(int);//empiler
    virtual void operator>(int&);//depiler
    virtual void printToStream(ostream&) const;
    friend ostream & operator<<(ostream &, const DataStructure &);
};
//__________________________________________________________________________________
//Definition des objets de Class  << DataStructure >> -----------------
//___________________________________________________________________________________
DataStructure::DataStructure(int n = 10)
{
  size = n;
  p = new int[size];
}

DataStructure::DataStructure(const DataStructure& ds)//constructeur par recopie
{
  DataStructure(ds.getSize());

  for (int i = 0; i < size; i++)
    p[i] = ds[i];
}

DataStructure::~DataStructure()
{
  delete[] p;
}

void DataStructure::operator<(int x)
{
  *p = x;
}

void DataStructure::operator>(int& x)
{
  x = *p;
}

void DataStructure::printToStream(ostream& outPut) const
{
  outPut << *p;
}

ostream& operator<<(ostream& outPut, const DataStructure& ds)
{
  ds.printToStream(outPut);
  return outPut;
}

//Class Lifo  ###################################################

class Lifo: public DataStructure
{
  private:
    int summit;
  public:
    Lifo(int);
    Lifo(Lifo&);
    ~Lifo() {}
    int getSummit() { return summit; }
    void operator<(int);
    void operator>(int&);
    void printToStream(ostream&) const;
};
//___________________________________________________________________________________
//Definition des objets Class   << Lifo >> -----------------
//___________________________________________________________________________________
Lifo::Lifo(int n = 10): DataStructure(n)
{
  summit = 0;
}

Lifo::Lifo(Lifo& l)
{
 
  size = l.getSize();
  summit = l.getSummit();
  for (int i = 0; i < summit; i++)
    p[i] = l[i];
}

void Lifo::operator<(int x) //empiler
{
  p[summit] = x;
  summit++;
}

void Lifo::operator>(int& x) //dépiler
{
  summit--;
  x = p[summit];
}

void Lifo::printToStream(ostream& outPut) const
{
  for (int i = 0; i < summit; i++)
    outPut << p[i] << " ";
}

//Class Fifo  ##################################################

class Fifo: public DataStructure
{
  private:
    int queue;
    int head;
  public:
    Fifo(int);
    Fifo(Fifo&);
    ~Fifo() {}
    int getQueue() const { return queue; }
    int getHead() const { return head; }
    void operator<(int);
    void operator>(int&);
    void printToStream(ostream&) const;
};

//___________________________________________________________________________________
//Definition des objets Classe   << Fifo >> -----------------
//___________________________________________________________________________________
Fifo::Fifo(int n = 10):DataStructure(n)
{
  queue = 0;
  head = 0;
}

Fifo::Fifo(Fifo& f)//constructeur par recopie
{
  queue = f.getQueue();
  head = f.getHead();
  size = f.getSize();

  for (int i = head; i < queue; i++)
    p[i] = f[i];
}

void Fifo::operator<(int x) //empiler
{
  p[queue] = x;
  queue++;
}

void Fifo::operator>(int& x) //dépiler
{
  x = p[head];
  head++;
}

void Fifo::printToStream(ostream& outPut) const
{
  for (int i = head; i < queue; i++)
    outPut << p[i] << " ";
}

//######################################################################################
             //---------------------Programme principal-----------------
//######################################################################################
void test(DataStructure& ds)
{
  int i;

  // On empile
  ds < 0;
  ds < 1;
 
  // On affiche le contenu
  cout << "Etat de la structure : " << endl;
  cout << ds << endl;

  // On enlève une valeur
  ds > i;

  // On affiche la valeur
  cout << "Valeur enlevée : " << endl;
  cout << i << endl;
}

int main()
{
  Lifo lifo;
  Fifo fifo;

  cout << "#### Test de la LIFO" << endl;
  test(lifo);
 
  cout << endl;

  cout << "#### Test de la FIFO" << endl;
  test(fifo);

  return 0;
}
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de cs_rt15
cs_yex 28 Messages postés jeudi 3 octobre 2002Date d'inscription 31 mai 2010 Dernière intervention - 27 déc. 2008 à 19:39
0
Utile
Pourquoi ne pas utiliser la STL plutôt que de refaire sans cesse les même classes ?
Commenter la réponse de cs_yex
nickydaquick 417 Messages postés vendredi 31 janvier 2003Date d'inscription 19 décembre 2013 Dernière intervention - 27 déc. 2008 à 21:34
0
Utile
Salut,
1- tu crees dans le header un constructeur avec arguments (basepile(int), lifo(int), fifo(int) ) alors que dans la source tu le veux a la fois avec arguments et par defaut. CA NE MARCHE PAS COMME CA.

basepile( int argument= 0); //dans le header
basepile::basepile(int argument) //dans la source
{
}

2- vu que tu as un pointeur que tu essaies de detruire dans la classe de base : definis le destructeur en virtual dans toutes les classes, et verifies ton pointeur avant de le detruire

3- ce n'est pas comme ca que l'on surcharge les operateurs < et  >.  En pratique lorsqu'une fonction est virtuelle dans la classe mere , elle devrait l'etre dans les classes filles.


4- honnetement je ne suis pas stroustrup(createur du c++), mais ton Programme principal est un mess total

En conclusion, je te conseille vivement de revoir le cours a ce niveau ( les 3 remarques) , cea devrait etre suffisant pour corriger adequatement ton code :-)

Je te souhaite une bonne continuation, au revoir.

je suis heureux de faire partie d'une grande famille ...!

/B&
Commenter la réponse de nickydaquick
cs_rt15 3982 Messages postés mardi 8 mars 2005Date d'inscription 7 novembre 2014 Dernière intervention - 27 déc. 2008 à 23:44
0
Utile
Croisement de post (De deux heures)... Marrant, on dirait que j'ai pas reçu
de notification.



1- tu crees dans le header un constructeur avec arguments
(basepile(int), lifo(int), fifo(int) ) alors que dans la source tu le
veux a la fois avec arguments et par defaut. CA NE MARCHE PAS COMME CA.



Bin on dirait que si en fait. On dirait qu'il considère le constructeur avec un int comme constructeur par défaut vu qu'il prend un entier. Mais bon c'est clair que c'est un peu à la ça va peut être tomber sur le bon constructeur.

3- ce n'est pas comme
ca que l'on surcharge les operateurs < et  >.  En pratique
lorsqu'une fonction est virtuelle dans la classe mere , elle devrait
l'etre dans les classes filles.

Bin c'est pas obligé en fait. Même si le compilo va compiler comme si elle était virtuelle. Par exemple, chez dev.com ils ne l'ont pas fait.
Commenter la réponse de cs_rt15

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.