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 :

tableau héritage classe abstraite


Sujet :

C++

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 28
    Points : 10
    Points
    10
    Par défaut tableau héritage classe abstraite
    Bonjour,

    J ai 2 classes escalade et randonnée qui héritent d une classe activité abstraite.
    J ai une classe sport qui contient un tableau d activités.

    Extrait de la classe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class Sportif : public Naturel
    {
    private:
        int _inbAct;
        Activitee *_tabAct;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Sportif::Sportif() : Naturel()
    {
    _tabAct = NULL;
    _inbAct = 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void Sportif::AjouterAct(const Activitee * act){
        Activitee *tab[_inbAct+1];
        for (int i = 0; i <_inbAct; i++ )
            tab[i] = _tabAct[i];
        tab[_inbAct] = act;
        delete []_tabAct;
        _tabAct = tab;
        _inbAct ++;
    }


    Dans ajouter avant de connaitre le classes abstraite, je faisais un tableau intermédiaire de taille n +1 avec l objet ajouter. Je supprimer l ancien tableau puis j échanger les pointeurs. Afin d avoir un tableau de taille variable.

    Sauf que je n y arrive pas là à faire passer un pointeur d activité en paramètre.
    Enfin je suis perdu, j ai l’impression que tab n est pas un pointeur d Activitée donc ça plante mais j ai pas le droit de faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Activitee *tab = new Activitee[_inbAct+1];
    car Activitee est une classe abstraite...

    Activitee

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 131
    Points : 33 074
    Points
    33 074
    Billets dans le blog
    4
    Par défaut
    Bonjour,

    Activite[100] déclare 100 objet Activite.
    Pour déclarer 100 pointeur sur Activite, la syntaxe c'est Activite*[100].

    Activite* est un pointeur sur Activite, peut également être utilisé comme tableau en pointant sur le premier élément d'une liste contigue dActivite.
    Pour avoir un tableau de pointeur, il faut alors déclarer Activite**. De la même manière, cette syntaxe peut autant définir un tableau sur Activite*, ou un tableau 2dimensions sur Activite.
    etc..

    Sinon, on a inventé std::vector depuis !

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 28
    Points : 10
    Points
    10
    Par défaut
    Okay, merci pour l aide.
    Enfet
    Activitee *tab = new Activitee[100];
    et
    Activitee **tab;
    et
    Activitee *tab[100];

    représente la même chose ?

    Merci pour l aide. Et non je ne peut pas utiliser vector dans le cadre de mon devoir.

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 131
    Points : 33 074
    Points
    33 074
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par zeracoa Voir le message
    Activitee *tab = new Activitee[100];
    et
    Activitee **tab;
    et
    Activitee *tab[100];

    représente la même chose ?
    Absolument pas.
    Cf ce que j'ai raconté plus haut :
    - dans le premier cas tu as un tableau de Activitee
    - dans le second cas tu as un pointeur sur pointeur. Qui peut être utilisé comme tableau de pointeur ou tableau 2 dimensions.
    - dans le 3° cas tu as 100 pointeur contigüs. Que tu peux utiliser comme tableau 2 dimensions ou 100 pointeurs.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 28
    Points : 10
    Points
    10
    Par défaut
    Okay c est clair maintenant.

    Donc je peut pas utiliser la première solution car j ai une classe abstraite.

    Je souhaite utiliser la 3e mais j'ai une erreur de segmentation au moment d accéder à l'élément du tableaux donc il n enregistre pas le pointeur vers act dans le tableau. J ai modifié un peu le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class Sportif : public Naturel
    {
    private:
        int _inbAct;
        Activitee **_tabAct;
     
    public:
        Sportif();
        Sportif(const string &);
        virtual ~Sportif();
        virtual void Affiche()const;
        friend ostream& operator<<( ostream &,const Sportif &);
        void AjouterAct( Activitee *);
    };
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Sportif::Sportif() : Naturel()
    {
    _tabAct = NULL;
    _inbAct = 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void Sportif::AjouterAct( Activitee * act){
        //act->Affiche();   //cela fonctionne donc *act est bon
        Activitee *tab[_inbAct+1];
        for (int i = 0; i <_inbAct; i++ )
            tab[i] = _tabAct[i];
        tab[_inbAct] = act;
        delete []_tabAct;
        _tabAct = tab;
        _inbAct ++;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void Sportif::Affiche()const{
        cout << "******************************** " << endl
             << "   Information sur le lieux " << endl
             << "******************************** " << endl
             << "Nom du lieux : " << _sNom << endl
             << "******************************** " << endl
             << "   Information sur les activités " << endl
             << "******************************** " << endl;
        for(int i = 0; i < _inbAct; i++) // c est ici que çà bug
            _tabAct[i]->Affiche();
    }

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 131
    Points : 33 074
    Points
    33 074
    Billets dans le blog
    4
    Par défaut
    Pour allouer un tableau, il faut utiliser l'opérateur new[].
    Il est impossible de définir un tableau comme tu le fais Activitee *tab[_inbAct+1];. (En fait ça a été possible fut un temps en C mais ce n'est pas le sujet).

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 28
    Points : 10
    Points
    10
    Par défaut
    Oaui mais je ne peut pas utiliser new car je ne peut pas creer d instance de Activitee.
    Ou sinon ma syntaxe est mauvaise.
    Je fait Activitee **tab = new Activitee[_inbAct+1];
    Et ca me dit cannot allocate an object of abstract type 'Activitee'

    Si je fait :
    Activitee **tab = new Activitee*[_inbAct+1];

    La fonction affiche ne m affiche rien après...

  8. #8
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 131
    Points : 33 074
    Points
    33 074
    Billets dans le blog
    4
    Par défaut
    Je serais curieux de voir quelle erreur tu rencontres puisque Activitee **tab = new Activitee*[_inbAct+1]; est définitivement la bonne initialisation.
    Si Affiche ne fait rien, le problème vient plus que surement d'elle et non d'une initialisation (enfin) correcte.

    Il faudrait revoir tes cours de base : l'allocation dynamique, le polymorphisme et l'héritage.

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 28
    Points : 10
    Points
    10
    Par défaut
    Oui je ne comprend pas du tout pourquoi ca ne marche pas.
    Je suis sur ce problème depuis hier soir et j ai lu pas mal d infos sur le polymorphisme et l héritage. Je pense avoir bien codé ces aspects.
    Après l allocation dynamique, j ai toujours eu plus de mal a appréhender les concepts qui changent tous le temps (C au premier semestre, et java l année dernière...). Mais comme tu dit Activitee **tab = new Activitee*[_inbAct+1]; devrait fonctionner.

    J avais réussi a faire marcher un tableau de pointeur de taille fixe lors de l implémentation de la classe Activitée et de ses fils.
    Mais j ai ensuite voulu faire un tableau de taille variable quand j ai implémenté la classe Sportif. Et vu que c est la première fois que j en fait un d une classe abstraite bha j ai jamais vu comment implémenter ça.

    Si je ne trouve pas je reviendrais à une taille fixe...

    Sinon si ca peut éclairer la situation j ai essayé de lancer en mode déboguage (avec qt sous windows), j obtient:

    terminate called after throwing an instance of 'std::bad_alloc'
    what<>: std::bad_alloc

    edit: j avais test affiche en faisant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void Sportif::AjouterAct( Activitee * act){
        act->Affiche();   //cela fonctionne donc affiche marche
    //Activitee *tab[_inbAct+1];
        Activitee **tab = new Activitee*[_inbAct+1];
        for (int i = 0; i <_inbAct; i++ )
            tab[i] = _tabAct[i];
        tab[_inbAct] = act;
        delete []_tabAct;
        _tabAct = tab;
        _inbAct ++;
    }

  10. #10
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 131
    Points : 33 074
    Points
    33 074
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par zeracoa Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Activitee *tab[_inbAct+1];
    J'espère qu'il s'agit d'un mauvais copier/coller, parce que sinon je te renvois vers les messages précédents et aurais l'impression de perdre mon temps.

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 28
    Points : 10
    Points
    10
    Par défaut
    Oui j ai copié depuis le message précédent et non depuis le code actuel.
    Je modifie le message précédent en remettant tout bien en cas que quelqu’un d autre lise pour pouvoir s y retrouver.

  12. #12
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 28
    Points : 10
    Points
    10
    Par défaut
    Je me penche sur un autre soucis de conception.

    Si je fait

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Activitee* act;
    Escalade* esca;
    Randonee* rando;
     
    act = esca;
    Es que je peut ensuite savoir que act contient un pointeur vers Escalade et non vers Randonee ?

  13. #13
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 589
    Points
    41 589
    Par défaut
    C'est possible, mais généralement considéré comme "tricher" et le fait d'en avoir besoin est considéré comme un symptôme d'une possible erreur de conception.

  14. #14
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 28
    Points : 10
    Points
    10
    Par défaut
    Comment faire pour une fonction modifierActivitee(Activitée *) du coup ?

  15. #15
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 589
    Points
    41 589
    Par défaut
    En lui faisant appeler une fonction virtuelle Activite::modifier()?
    Dans l'implémentation des fonctions virtuelles, les objets dérivés connaissent leur propre type.

  16. #16
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 28
    Points : 10
    Points
    10
    Par défaut
    Okay, merci je n y avait pas pensé !

    Sinon pour mon problème du dessus j ai essayé d utiliser un tableau de taille fixe mais rien a faire toujours une segmentation fault à ce moment : _tabAct[_inbAct] = act; .

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class Sportif : public Naturel
    {
    private:
        int _inbAct;
        Activitee** _tabAct;
    };
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Sportif::Sportif() : Naturel()
    {
    _inbAct = 0;
    _tabAct = new Activitee*[5];
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void Sportif::AjouterAct( Activitee * act){
      //  act->Affiche();
      _tabAct[_inbAct] = act;
      _inbAct ++;
    }

  17. #17
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 589
    Points
    41 589
    Par défaut
    Pourquoi ne pas utiliser un std::vector à la place de ton tableau nu? Cela t'est-il interdit?

  18. #18
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 28
    Points : 10
    Points
    10
    Par défaut
    Oui je ne peut pas utiliser vector.

    Je vient de trouver mon erreur.

    J utiliser un autre constructeur pour instancier et j avais pas mis
    _inbAct = 0;
    C est étrange car je pensais que le fait de faire int _inbAct; par défaut ca mettait _inbAct à 0.

  19. #19
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 131
    Points : 33 074
    Points
    33 074
    Billets dans le blog
    4
    Par défaut
    En C++, déclarer une variable ne fait aucune action d'initialisation sur celle-ci, sauf s'il s'agit d'un type complexe qui possède un constructeur par défaut.

    int i; déclare un int, le pc fournit une adresse qui contient la valeur de l'int, et la "valeur par défaut" n'est donc autre que ce qu'on trouvait auparavant à son emplacement mémoire.

Discussions similaires

  1. héritage classes abstraites
    Par seroa dans le forum Langage
    Réponses: 4
    Dernier message: 12/10/2009, 15h31
  2. héritage, classe abstraite
    Par sebatlante dans le forum C++
    Réponses: 4
    Dernier message: 14/08/2009, 14h13
  3. héritage - classes abstraites
    Par Invité dans le forum C++
    Réponses: 2
    Dernier message: 03/05/2009, 13h17
  4. Tableau et classe abstraite
    Par NFHnv dans le forum Collection et Stream
    Réponses: 2
    Dernier message: 18/03/2009, 16h28
  5. Tableau et classes abstraites
    Par HNoury dans le forum Collection et Stream
    Réponses: 13
    Dernier message: 02/06/2007, 20h49

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