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 :

La destruction d'un objet d'une classe fille


Sujet :

C++

  1. #1
    Membre du Club
    Homme Profil pro
    12
    Inscrit en
    Mai 2014
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : 12
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 67
    Points : 61
    Points
    61
    Par défaut La destruction d'un objet d'une classe fille
    bonsoir, pour pouvoir détruire un objet d'une classe fille il faut que le destructeur de la classe mère soit protegé et non virtual ou bien public et virtual
    mais pourquoi donc ce code génère une erreure :
    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
     
    #include <iostream>
    class mere
    {
        protected:
            ~mere()
            {
                std::cout<<"destructeur de mere\n";
            }
    };
    class fille :public base
    {
        ~fille()
        {
            std::cout<<"destructeur de fille\n";
        }
    };
    int main()
    {
        mere *p_b = new fille;
        std::cout<<"Destruction de l'objet :\n";
        delete p_b; // -> Erreur de compilation
        return 0;
    }

  2. #2
    Membre du Club
    Homme Profil pro
    12
    Inscrit en
    Mai 2014
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : 12
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 67
    Points : 61
    Points
    61
    Par défaut
    je viens de remarquer que le destructeur est declaré protegé !
    donc la solution sera de le decalré public et virtual

  3. #3
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 627
    Points : 30 692
    Points
    30 692
    Par défaut
    Salut,
    Citation Envoyé par DLOYAS Voir le message
    je viens de remarquer que le destructeur est declaré protegé !
    donc la solution sera de le decalré public et virtual
    En effet...

    Il est légal de déclarer le destructeur de la classe de base comme étant non virtuel et dans l'accessibilité protégée, mais cela implique une restriction très fortes sur la destructions des instances des classes dérivées dans le sens où nous sommes obligés de les détruire en tant qu'instances du type dérivé que l'on ne peut pas décider de détruire un objet qui "passerait pour être du type de base".

    Il est parfois très intéressant d'agir de la sorte, car cela te donne l'assurance qu'une fonction qui prend un pointeur du type de base ne pourra pas essayer d'appeler delete sur ce pointeur (et donc, risquer d'invalider l'objet qu'elle a recu en argument au travers de ce pointeur). Mais cela signifie aussi que "ce qui s'occupera de gérer la durée de vie" des objets de type dérivé devra veiller à... ne pas perdre de vue qu'il s'agit d'objets du type dérivé

    Or, bien souvent, on se trouve dans une situation dans laquelle "on n'en n'a rien à foutre" du type réel des différents objets parce que l'on considère qu'il s'agit de toutes façons d'objet du type de base et que toutes les manipulations qui pourraient être faites se baseront sur ce fait.

    Dans cette situation, nous n'allons pas créer une collection différente pour chaque type dérivé, mais plutôt une collection de pointeurs (de préférence intelligents) sur des objets du type de base. Et, pour pouvoir détruire les différents objets, il faut que
    1. la fonction de destruction de l'objet (celle qui appellera delete) puisse accéder au destructeur du type de base et que
    2. le compilateur se rend compte qu'il devra adapter le comportement du destructeur du type de base au type réel de l'objet

    Le (1) implique que le destructeur doit être public, le (2) implique que le destructeur doit être virtuel.

    Quelques exemples précis :
    Mettons que tu aies des Clients et des Fournisseurs, tous deux dérivés de Personne. Tu ne vas jamais "mélanger" les clients et les fournisseurs. Tu vas donc les mettre dans des collections différentes et ou bien tu travailleras sur la liste de tes fournisseurs, ou bien tu travailleras sur la liste de tes clients.

    Et une chose est sure : si tu décide, à un moment donné, de travailler avec un pointeur sur une Personne, la fonction qui utilise ce pointeur ne peut faire qu'utiliser l'objet transmis sous la forme de ce pointeur. Tu peux donc déclarer le destructeur de Personne dans l'accessibilité protégée (pour que les classes Client et Fournisseur puissent y accéder) mais non virtuel, car il n'y a aucun besoin de permettre la modification de son comportement.

    Maintenant, imaginons que tu veuilles créer des objets qui doivent être affichés. Mettons que la classe de base soit DrawableObject et que tu aies une hierarchie de classe contenant une classe Wall (les murs, lorsqu'il faut les afficher), Stone (des pierres, sur le chemin), Spell (les sorts lancés par les joueurs), PNJ (personnages non joueur) et que sais-je d'autre...

    Quel que soit le type réel de tous les objets que tu va créer, tu vas vouloir les placer dans une seule et unique collection afin de pouvoir... provoquer l'affichage de tous les éléments affichables, indépendamment de leur type réel, sous une forme qui pourrait être proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    // C++11 inside
    for (DrawableObject * it : maCollection){
        it->draw(render);
    }
    Et, bien sur, lorsqu'il s'agira de détruire un des éléments, tu devras le détruire en le connaissant "sous la forme d'un pointeur de type DrawableItem", quel que soit le type réel de l'élément que tu veux détruire, par exemple, sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    // C++11 inside
    for (DrawableObject * it : maCollection){
        delete it; // on aura sans doute eu recours aux pointeurs intelligents mais, 
                   // on va dire que c'est pas le cas, uniquement pour l'explication ;)
    }
    Il faudra donc que le destructeur de DrawableItem soit public (pour que le compilateur accepte que tu appelle delete sur le pointeur) et virtuel (pour qu'il (le compilateur) se rende compte que le comportement doit être adapté au type réel de l'objet)

    In n'y a aucune règle qui dise, d'une manière ou d'une autre, qu'une situation est plus fréquente que l'autre. La seule règle est de faire le bon choix en fonction de tes besoins

Discussions similaires

  1. Réponses: 6
    Dernier message: 21/05/2006, 20h37
  2. [POO] import d'objet dans une classe
    Par wdionysos dans le forum Langage
    Réponses: 3
    Dernier message: 01/04/2006, 21h05
  3. Réponses: 4
    Dernier message: 08/03/2006, 19h07
  4. Réponses: 19
    Dernier message: 02/02/2006, 23h30

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