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 :

Notion d'héritage et de classes abstraites


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2008
    Messages
    138
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Janvier 2008
    Messages : 138
    Par défaut Notion d'héritage et de classes abstraites
    Bonsoir à tous.


    Voilà, j'ai un problème avec la notion d'héritage avec des classes abstraites et des méthodes virtuelles. L'héritage se fait sur trois niveaux :

    Voici la déclaration de la classe de base :

    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
     
    class Contenu
    {
      	private :
    		//Attributs
    		std::string _nomTypeContenu; //prend la valeur CONTENU_ANIMAL ou CONTENU_VIDE
    		int _x; //Abscisse de la case
    		int _y; //Ordonnée de la case
     
    	public :
    		//Méthodes
                    //Contenu(std::string = CONTENU_VIDE, int = 0, int = 0); //Constructeur
    		void setAbscisse(int x) { _x = x;};
    		void setOrdonnee(int y) {_y = y;};
    		bool operator == (Contenu) const; //surdéfinition de l'opérateur de comparaison;
            virtual void deplacer(const int[][MAX]) = 0; //Déplacement d'un animal
    		virtual void retirer(int [][TAILLE_REELLE]) = 0; //Retire un animal
    };

    Et voici la déclaration de ses classes dérivées :

    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
     
    //classe fille de Contenu
    class Animal : public Contenu
    {
        protected :
    		//Attributs
    		int _population ;
     
    	public :
    		//Méthodes
    		Animal(int = 0) ; //Constructeur
    		virtual void deplacer(const int[][MAX]); //Déplacement d'un animal
    		virtual void retirer(int [][TAILLE_REELLE]); //Retire un animal
    };
     
    //classe vide fille de Contenu
    class Vide : public Contenu
    {
        //vide
    };
     
    //classe mur
    class Mur : public Contenu
    {
    };
    Et enfin, les classe elles-mêmes dérivées de la classe Animal :

    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
     
    //classe fille de Animal et petite fille de Contenu
    class Poule : public Animal
    {
    	private :
    		//Attributs
            int _nbPv ;
     
            //variables statiques
            static  char _predateurPoule;
            static  char _proiePoule;
            static int _nbPoule;
     
     
    	public :
    		//Méthodes
    		Poule(int = 50); //Constructeur
    		int getNbPv() { return _nbPv;};
    };
     
    //classe fille de Animal et petite fille de Contenu
    class Renard : public Animal
    {
    	private :
    		//Attributs
    		int _nbPv;
     
    		//vriables statiques
            static char _proieRenard;
            static char _predateurRenard;
    		static int _nbRenard;
     
     
    	public :
    		//Méthodes
    		Renard(int =  50);//Constructeur
     
    };
     
     
    //classe fille de Animal et petite fille de Contenu
    class Vipere : public Animal
    {
    	private :
    		//Attributs
    		int _nbPv ;
     
    		//variables statiques
            static char _proieVipere;
            static char _predateurVipere;
    		static int _nbVipere;
     
    	public :
    		//Méthodes
    		Vipere(int =  50);//Constructeur
     
    };

    Comme ça le problème est posé.

    Je n'ai pas encore vu la notion de classe abstraite, mais j'ai compris son fonctionnement.
    J'ai mis le constructeur de "Contenu" en commentaire. Ai-je le droit de créer cette classe en laissant le constructeur par défaut, sachant qu'elle est virtuelle?

    Car en fait quand je teste ce main :

    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
     
    int main() {
     
        Contenu c1;
        Contenu *c;
        Poule p1;
        Poule *p;
     
        *p = *c;
     
        cout << "le nombre de points de vie est " << p1.getNbPv() << endl;
     
        return 0;
     
    }
    J'obtiens les erreurs suivantes :

    error : cannot declare variable 'c1' to be of type 'Contenu'
    error : because the following functions are abstract
    error : virtual void Contenu::retirer(int (*)[8])
    error : virtual void Contenu::deplacer(const int (*)[100])




    Merci d'avance à ceux qui veulent bien m'éclairer sur cette notion de classes abstraites. Pourquoi ici elles posent problèmes?

  2. #2
    Membre chevronné Avatar de icer
    Inscrit en
    Janvier 2006
    Messages
    332
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 332
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int main() {
     
        Contenu c1;
    Tu essaies d'instancier une classe abstraite. Or une classe asbtraite est par définition non instanciable. Car ses fonctions virtuelles ne sont pas définies, il est donc impossible de les invoquer. Ce que le compilateur signal :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    error : because the following functions are abstract
    error : virtual void Contenu::retirer(int (*)[8])
    error : virtual void Contenu::deplacer(const int (*)[100])
    Par contre, il est possible de déclarer un pointeur Contenu* et le faire pointer vers une classe dérivé: cela permet le polymorphisme... c'est l'interet des classes abstraites et des méthode virtuelles.

    Je ne comprend pas ce que tu veux faire en déclarant des pointeurs qui ne pointent nullpart (plus précissement n'importe où en mémoire, trés dangereux!).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    int main() {
     
        Contenu c1;
        Contenu *c;
        Poule p1;
        Poule *p;
     
        *p = *c;
     
        cout << "le nombre de points de vie est " << p1.getNbPv() << endl;
     
        return 0;
     
    }

  3. #3
    Membre confirmé
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2008
    Messages
    138
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Janvier 2008
    Messages : 138
    Par défaut
    Oui pardon en fait c'est parce que je n'ai pas été assez précis.

    En réalité, mon but est de créer un tableau qui puisse contenir n'importe quel objet de type dérivée de Contenu.
    J'avais donc pour idée première de déclarer un tableau de type Contenu, mais cela implique d'instancer des objets d'une classe abstraite (interdit comme tu me l'as rappelé et comme on me l'a rappelé sur le SDZ).

    Je précise que je suis en 1ère année de DUT info et que les classes abstraites ne sont vues qu'en 2ème.

    Donc au final je devrai plutot faire un tableau de pointeurs de Contenu et l'utiliser ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    int main() {
     
        Contenu* tab[10];
        Poule p1;
        Poule *p = &p1;
     
        tab[1] = p;
     
        cout << "le nombre de points de vie est " << (*tab[1]).getNbPv() << endl;
     
        return 0;
     
    }
    C'est bien cela?

    Si je comprends bien, le polymorphisme permet de "traverser" la classe Contenu pour recherche les méthodes des objets de type correspondant ...
    En tout cas ça semble être la solution à ma situation.

    Merci en tout cas, ça m'a drôlement éclairé sur ces notions.

  4. #4
    Membre chevronné Avatar de icer
    Inscrit en
    Janvier 2006
    Messages
    332
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 332
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cout << "le nombre de points de vie est " << (*tab[1]).getNbPv() << endl;
    Tu ne peux pas appeler la méthode getNbPv() car tab[10] est un tableau de type Contenu* et cette classe n'a pas de méthode getNbPv().

    Pour que cela fonctionne la méthode getNbPv() doit être déclaré en tant que virtuelle dans la classe Contenu.

    Je précise que je suis en 1ère année de DUT info et que les classes abstraites ne sont vues qu'en 2ème.
    C'est bien de prendre de l'avance .

    Si je comprends bien, le polymorphisme permet de "traverser" la classe Contenu pour recherche les méthodes des objets de type correspondant ...
    Si les méthodes appelées sont déclarées virtuelles dans la classe de base : oui.

  5. #5
    Membre confirmé
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2008
    Messages
    138
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Janvier 2008
    Messages : 138
    Par défaut
    Ok cette fois c'est bon, j'ai pigé l'utilisation de tout cela, et c'est exactement la solution à la situation.

    Merci

    Peut-être que je reviendrai poser des questions sur l'héritage et le polymorphisme.

Discussions similaires

  1. héritage d'une classe abstraite
    Par new_wave dans le forum Langage
    Réponses: 8
    Dernier message: 04/03/2010, 12h54
  2. [Conception] Héritage sur Plusieurs classes abstraites
    Par facilus68 dans le forum Langage
    Réponses: 9
    Dernier message: 20/03/2009, 13h06
  3. Problème d'héritage avec une classe abstraite
    Par Ph.denis dans le forum C++
    Réponses: 7
    Dernier message: 22/03/2008, 10h37
  4. Erreur du designer avec héritage d'une classe abstraite
    Par Xzander dans le forum Windows Forms
    Réponses: 4
    Dernier message: 04/04/2007, 00h36
  5. Conception: héritage d'une classe abstraite
    Par Kikito dans le forum Langage
    Réponses: 19
    Dernier message: 05/10/2006, 17h36

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