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 :

Probleme avec le polymorphisme et les templates :(


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    74
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2005
    Messages : 74
    Points : 29
    Points
    29
    Par défaut Probleme avec le polymorphisme et les templates :(
    bonjour a tous,

    excusez moi du dérangement mais voila,j ai un gros probleme avec le

    polymorphisme et les templates en C++

    et je dois rendre un exercice a mon prof pour mercredi soir au plus tard

    je vous explique en quelque mot ce que mon programme doit faire :

    - tout d abord,on as une classe Billet (qui est abstraite,c est a dire qu on ne peut pas créer d objet de ce type).

    - ensuite on a une classe EuroBillet (abstraite également) qui hérite de la classe Billet

    - ensuite on a une multitude de classes telles que : EuroB5,EuroB10,EuroB20,etc .... qui héritent de la classe EuroBillet

    - fiinalement,on a une classe totalement independante des autres, appellée : Portefeuille

    dans cette classe Portefeuille,c est donc un pointeur sur tableau de pointeurs sur objet de cette maniere :

    Billet ** _TabPort ;

    - dans ce portefeuille donc,on doit etre capable d y placer des objets de differentes classes (EuroB5,EuroB10,etc...)

    je dois donc utiliser les fonctions virtuelles et les templates.

    les fonctions virtuelles j ai réussit a les faire.

    mais les templates,j y comprends rien car j étais malade,le jour ou ils ont vu ca en classe

    pour ne pas flooder ici , je vous mets le lien ou vous pouvez prendre mon code

    ce serait sympa de m'aider ,et je vous en remercie tous d'avance

    http://perso.latribu.com/softstar/portefeuille.cpp

    PS : on utilise Dev C++

  2. #2
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    En fait, on peut sans doute dire que tes billets sont des classes templates héritant de EuroBillet.
    Pourquoi ?
    Parce que ces billets ont une valeur générique, 5€, 10€, 20€ qui est connue à la compilation.
    Donc outre ta classe EuroBillet, tu auras une classe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    template<unsigned int Valeur>
    classe EuroB : public EuroBillet
    {
    public:
      EuroB()
      :EuroBillet(Valeur)
      {}
    }
    En admettant que c'est l'objet parent qui gère la valeur du billet.

    edit : après avoir regardé ton code, c'est en gros ça que tu vas faire, le constructeur fils appelle le constructeur père avec la bonne valeur de la monnaie et la vraie valeur - imontant -

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    74
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2005
    Messages : 74
    Points : 29
    Points
    29
    Par défaut
    merci,mais ca ne fonctionne pas

    quand je compile,ca me mets ceci :

    128 C:\PROGRAMMATION\C++\GI3_C++_NEW\MesProg\portefeuille\portefeuille.cpp

    multiple types in one declaration

  4. #4
    Membre habitué 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
    Points : 185
    Points
    185
    Par défaut
    Bonjour,
    je ne vais pas te faire un cours sur les templates, et je ne vais pas non plus faire le code.

    Tu peux déjà regarder les templates, c'est dans la faq C++ de developpez. Sinon, tu peux très bien utiliser ton portefeuille sans template (ton prof t'oblige peut-être à les utiliser).
    Le code ressemblerait à ceci avec la déclaration Billet ** _TabPort; :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    _TabPort = new Billet [50];
    _TabPort[0] = new EuroB5();
    _TabPort[1] = new EuroB10();
    ...
    Donc ici, tu n'utilises pas de template. Je pense que votre prof voudrait peut-être un truc du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    _TabPort = new Billet [50];
    _TabPort[0] = new Billet<EuroB5>;
    _TabPort[1] = new Billet<EuroB10>;
    ...
    Donc la par contre tu utilises les templates, je pense (voir d'autres avis) que tu dois juste rendre Billet template (je crois pas que EuroBillet ait besoin de l'être).

    Euh, j'espere que j'ai répondu à une partie de la question car Miles rend template la valeur du billet.

    Bonne journée.

    b Oo
    b Oo

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    74
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2005
    Messages : 74
    Points : 29
    Points
    29
    Par défaut
    merci b O o , ca je suis arrivé a le faire,j'arrive a placer des billets de n importe quel type dans mon portefeuille

    par contre,la ou ca coince , c est quand par exemple j utilise la fonction :

    DelBillet(uint pos) ; // on retire un billet du portefeuille

    car je dois renvoyer le billet par référence
    (pour par exemple pouvoir l utiliser pour faire un achat , c'est symbolique bien sur)

    et si je renvoye un objet de type Billet comme ceci :

    Billet & DelBillet(uitn pos)

    ben,le programme plante en me disant que je ne peut renvoyer un objet de type billet car Billet est une classe abstraite

    donc je suppose que je doit utiliser les templates pour dire a ma fonction
    DelBillet de renvoyer le bon type de billet

    mais je vois pas comment faire

    merci a tous de votre aide en tout cas

  6. #6
    Membre habitué 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
    Points : 185
    Points
    185
    Par défaut
    Je viens de voir ton programme, en fait, ce que j'ai écris précèdemment remet en question tout ton programme.

    Miles t'indique (je pense que ceci est le mieux), que lorsque tu définies ta classe EuroB template, cela t'évite de faire une classe pour chaque billet, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    EuroB<5> b5; //cree un billet de 5 euros
    EuroB<1à> b10; //cree un billet de 10 euros
    ...
    Donc cela va t'enlever pas mal de classes.
    Je te montre une classe template pour exemple :
    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
     
    template <class T = int> // = int permet de dire que par défaut T est int
    class TVecteur
    {
     public:
      TVecteur(int = 0);
      TVecteur(const TVecteur<T> &);
      void AddElement(const T & val);
      TVecteur<T> operator=(const TVecteur<T> &);
      virtual ~TVecteur();
     private:
      T * vect;
      int taille; // taille actuelle du tableau
      int capacite; // taille max du tableau
    };
     
    template <class T>
    TVecteur<T>::TVecteur(int _capacite):vect(0),taille(0), capacite(_capacite)
    {
      vect = new T [capacite];
    }
     
    template <class T>
    TVecteur<T>::TVecteur(const TVecteur<T> & v): vect(0), taille(0), capacite(0)
    {
      if (this != &v)
        Recopie(this, &v);
    }
     
    template <class T>
    void TVecteur<T>::AddElement(const T & val)
    {
      ...
    }
    template <class T>
    TVecteur<T> TVecteur<T>::operator=(const TVecteur<T> & v)
    {
      ...
    }
    Quand tu fais une classe template, la définition des méthodes doit se faire dans le .h

    b Oo
    b Oo

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    74
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2005
    Messages : 74
    Points : 29
    Points
    29
    Par défaut
    ohhh la la la la , tu viens de m'embrouiller la boo

    en fait,j ai pas le choix,le prof veut qu on utilise les classes que je t ai dites

    donc ,créer une classe template pour eviter de creer des classes séparées,ca le fera pas

    je rappelle mes classes obligatoires :

    Billet , classe abstraite

    EuroB , classe abstraite , qui hérite de Billet

    EuroB5,EuroB10,EuroB20,EuroB50,EuroB100 , qui héritent toutes de EuroB

    et Portefeuille qui est independant

    comme je l'ai dit auparavant,mon probleme c est dans la classe Pörtefeuille

    je crée mon portefeuille,j y mets les differents billets (EuroB5,EuroB10,etc..)

    mais c est quand je veut par exemple en supprimer un (l enlever du portefeuille pour l utiliser par la suite (donc le renvoyer par reference))

    que la ca plante car je vois pas comment lui dire dans la fonction DelItem(), que il doit renvoyer l'objet du type : EuroB5,
    ou EuroB10,
    ou EuroB20,
    ou EuroB50,
    ou EuroB100
    voila , je sais pas comment etre plus clair parfois je m y perds un peu , snifff

    merci en tout cas de votre aide,vous etes tous super

  8. #8
    Membre habitué 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
    Points : 185
    Points
    185
    Par défaut
    Je pense que le problème vient du fait que, DelBillet supprime le billet du portfeuille (donc tu ne l'as plus en mémoire) et donc tu ne pas retourner une référence de celui-ci car tu l'as supprimé.
    Par contre, si tu veux le recuperer dans le programme principal, tu ne peux faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Billet monBillet = monPorteFeuille.DelBillet();
    par contre tu peux faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Billet * monBillet = monPorteFeuille.DelBillet();
    Si DelBillet() renvoie un pointeur et si tu ne supprime pas le billet de la mémoire.

    J'espère que cela répond à ta question.

    b Oo

    Edit: "C'est bon j'ai bien compris là, c'est juste que dans le 1er post tu ne fais pas mention du problème de DelBillet"
    b Oo

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    74
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2005
    Messages : 74
    Points : 29
    Points
    29
    Par défaut
    bon je te montre ce que j ai fait,et ca me plante a la figure

    il compile sans probleme

    dans mon main() , je fais ceci :

    pf1.DelBillet(1);
    pf1.Display();

    donc je retire le billet a la position 1 du portefeuille (donc position 0 en c++)
    puis j affiche le contenu du portefeuille
    mais a l'execution , il m affiche bien ce que je veut
    puis windows fait l'erreur systeme suivante :

    l'instruction a "0x00409089" réference la memoire a "0x06fffffc" , la memoire ne peut pas etre "ecrite" , clicker sur ok pour terminer,clicker sur cancel pour debugguer le programme.

    voici ma fonction Delitem(),si vous savez m'aider :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Billet & DelBillet(uint pos){
            if (!IsBillet(pos)) throw "Erreur";
            total-=_TabPort[pos]->GetMontant();
            Billet & temp=*_TabPort[pos];
            delete _TabPort[pos];
            _TabPort[pos]=0;
     
            for(uint i=pos; i<_Contenance; i++) 
            {
            if (i+1<_Contenance) _TabPort[i]=_TabPort[i+1];
            else _TabPort[i]=0; 
            }
            return temp;
            }
    voila je vous remercie tous d'avance

  10. #10
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    74
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2005
    Messages : 74
    Points : 29
    Points
    29
    Par défaut
    plus personne , snif ?

  11. #11
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Citation Envoyé par softstar
    en fait,j ai pas le choix,le prof veut qu on utilise les classes que je t ai dites

    donc ,créer une classe template pour eviter de creer des classes séparées,ca le fera pas
    Bon, alors il faut les mettre où les templates ? Parce que là, il n'y a rien qui ne soit pas du polymorphisme "classique".

  12. #12
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    74
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2005
    Messages : 74
    Points : 29
    Points
    29
    Par défaut
    miles,possible que finalement je ne doivent pas utiliser les templates

    par contre,cfr mon post un peu plus haut

    j'ai un probleme avec ma fonction delbillet

    tu sais y jeter un oeil svp ? je t'en remercie d avance

  13. #13
    Membre habitué 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
    Points : 185
    Points
    185
    Par défaut
    Ben en fait tu déclares temp dans DelBillet, donc comme temp est une référence sur _TabPort[pos] que tu détruis juste après, temp ne fait plus référence à aucun objet.
    Voila pourquoi cela plante.
    Je pense que le code suivant fait ce que tu attends, mais la ca ne va compiler :
    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
     
    Billet & DelBillet(uint pos)
    {        
      if (!IsBillet(pos)) 
        throw "Erreur";
      total-=_TabPort[pos]->GetMontant();
      Billet temp = *_TabPort[pos]); /* va te dire que Billet est une classe abstraite */
      delete _TabPort[pos];        
      _TabPort[pos]=0;
      for(uint i=pos; i<_Contenance; i++)
      {        
        if (i+1<_Contenance) 
         _TabPort[i]=_TabPort[i+1];
        else _TabPort[i]=0;        
      }        
      return temp;
    }
    En plus, ici temp est un objet qui est détruit à la fin de la méthode, donc la référence sera encore invalide, mais cette fois dans le programme principal.

    Et maintenant le code que tu veux faire et qui je pense fonctionne :
    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
    Billet & DelBillet(uint pos)
    {        
      if (!IsBillet(pos)) 
        throw "Erreur";
      total-=_TabPort[pos]->GetMontant();
      Billet * temp = _TabPort[pos];        
      _TabPort[pos]=0;
      for(uint i=pos; i<_Contenance; i++)
      {        
        if (i+1<_Contenance) 
         _TabPort[i]=_TabPort[i+1];
        else
          _TabPort[i]=0;        
      }        
      return *temp;
    }
    La par contre, le problème c'est que pour le supprimer on va avoir du mal, (a moins que delete &nomdelref fonctionne, mais je ne suis pas sûr). Et en plus je ne sais pas s'il va pas te dire qu'on utilise Billet.

    Ce que je ferais, moi :
    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
     Billet * DelBillet(uint pos)
     {        
       if (!IsBillet(pos)) 
         throw "Erreur";
       total-=_TabPort[pos]->GetMontant();
       Billet * temp = _TabPort[pos]; 
       _TabPort[pos]=0;
       for(uint i=pos; i<_Contenance; i++)
       {        
         if (i+1<_Contenance) 
          _TabPort[i]=_TabPort[i+1];
         else 
         _TabPort[i]=0;        
       }        
       return temp;
    }
    Ici je pense qu'il n'y a pas de problème, il faut juste que tu n'oublis pas de faire un delete.

    Je sais que toi tu veux :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Billet & DelBillet(uint pos)
    Essaye le code 2, mais je ne suis pas convaincu que cela fonctionne.
    Sinon, si tu ne veux absolument pas de pointeur, alors il ne faut pas rendre Billet abstraite. Et alors ta méthode sera la suivante :
    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
     
     Billet DelBillet(uint pos)
     {        
       if (!IsBillet(pos)) 
         throw "Erreur";
       total-=_TabPort[pos]->GetMontant();
       Billet temp = _TabPort[pos];
       delete _TabPort[pos];
       _TabPort[pos]=0;
       for(uint i=pos; i<_Contenance; i++)
       {        
         if (i+1<_Contenance) 
          _TabPort[i]=_TabPort[i+1];
         else 
         _TabPort[i]=0;        
       }        
       return temp;
    }
    J'espere avoir été clair.

    A+

    b Oo
    b Oo

  14. #14
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    74
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2005
    Messages : 74
    Points : 29
    Points
    29
    Par défaut
    Merciiiiiii Booo

    ton code 2 fonctionne nickel

    merci encore a toi

  15. #15
    Membre habitué 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
    Points : 185
    Points
    185
    Par défaut
    Tant mieux,
    personnellement je pense qu'utiliser des références sur des objets alloués dynamiquement est source d'erreurs, donc fait attention à cette utilisation.

    Sinon, met le sujet à résolu (tu vas dans outils de discussion en hau tde ton 1er post et ensuite mettre sujet à résolu).

    Bonne journée.

    A+

    b Oo
    b Oo

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 06/07/2009, 11h22
  2. Probleme avec l MasterPage et les sousDossier d'un site
    Par DelphiCool dans le forum ASP.NET
    Réponses: 8
    Dernier message: 26/02/2008, 14h44
  3. Réponses: 3
    Dernier message: 17/11/2007, 18h59
  4. Probleme avec shutil.copytree et les partages reseau
    Par balisong dans le forum Général Python
    Réponses: 1
    Dernier message: 04/09/2007, 15h59
  5. simuler le polymorphisme via les templates
    Par ronaldino dans le forum C++
    Réponses: 10
    Dernier message: 28/11/2006, 00h15

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