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 :

Comment savoir qu'un objet est delete


Sujet :

C++

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    192
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 192
    Par défaut Comment savoir qu'un objet est delete
    Bonjour

    voila c'est simple

    J'ai plusieurs vectors qui contiennent des objets. Un même objet peut etre dans plusieurs vectors.

    mes objets ne contiennent rien d'autre que des int ou des String

    quand je parcours mes vectors pour supprimer mes objets, il arrive que je fasse plusieurs fois un delete sur un objet qui a deja été delete. Et donc c'est pas bon...

    Existe-il un moyens en C++ pour savoir si mon objet a déja été supprimé.

    merci a bientot

  2. #2
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Par défaut
    Normalement si tu règles le pointeur à NULL, après tu peux refaire un delete dessus sans problème, où bien vérifié s'il est est à NULL pour le supprimer.

    Sinon, avec les conteneurs de pointeurs de boost (ici, pour vector : http://www.boost.org/libs/ptr_contai...tr_vector.html), tu as une fonction nommée is_null, qui pourrait peut-être t'aider.

  3. #3
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Il y a un problème dans ton design - notamment la notion d'ownership est mal définie. Un objet appartient à une unique entité. A partir du moment ou un objet appartien à deux entités, il y a un problème.

    Le C++ ne permet pas de savoir si un objet a été détruit ou pas, mais il existe des mécanismes qui permettent de s'affranchir de ce "problème" (qui, selon moi n'est pas un problème). Une fois correctement défini qui doit être responsable de quoi, il est possible de de mettre en place une solution qui utilise la librairie smart pointer de boost (ou l'équivalent du TR1 si tu as à ta disposition un compilateur t'offrant la possibilité de l'utiliser tout ou en partie (gcc vient à l'esprit)). Le propriétaire d'un objet peut y accéder via un shared_ptr<>, et les autres objets qui tiennent unr référéence sur cet objet peuvent utiliser udes weak_ptr<>.

    Pour plus d'information, cf http://www.boost.org/libs/smart_ptr/smart_ptr.htm
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  4. #4
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Citation Envoyé par Emmanuel Deloget Voir le message
    A partir du moment ou un objet appartien à deux entités, il y a un problème.
    Je ne vois pas en quoi c'est un problème, les shared_ptr permettent justement d'avoir la notion de propriété partagée.

    Citation Envoyé par Emmanuel Deloget Voir le message
    Le propriétaire d'un objet peut y accéder via un shared_ptr<>, et les autres objets qui tiennent unr référéence sur cet objet peuvent utiliser udes weak_ptr<>.
    Les propriétaires d'un objet peuvent y accéder via un shared_ptr<>, et les autres objets qui tiennent unr référéence sur cet objet peuvent utiliser udes weak_ptr<>.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  5. #5
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Je ne vois pas en quoi c'est un problème, les shared_ptr permettent justement d'avoir la notion de propriété partagée.

    Les propriétaires d'un objet peuvent y accéder via un shared_ptr<>, et les autres objets qui tiennent unr référéence sur cet objet peuvent utiliser udes weak_ptr<>.
    Selon moi (mais ce n'est qu'un opinion), il est nécessaire de savoir qui est propriétaire de quoi à tout moment. Si deux conteneurs sont propriétaires d'un même objet et que l'un d'eux décide que cet objet doit être détruit, permettre à l'autre conteneur de continuer à l'utiliser est une erreur de logique. Par exemple, une particule dans un système de particules: le conteneur qui effectue l'update décide que la particule ets morte, mais le conteneur qui est utilisé dans le rendu continue de la croire vivante - au final, on affiche une particule que l'on est pas censé afficher et dont on ne modifie plus les propriétés.

    Les cas de relation many-to-many sont extrèmement rares. La plupart du temps, ils peuvent être remplacés par des relations one-to-many de manière triviale. De plus les relations M2M sont souvent complexes à gérer, et source de bugs difficiles à tracer - notamment dans des contextes de programmation concurrente. Elles necessitent souvent le non respect du principe de dépendance acyclique, ce qui entraine des couplages forts entre les objets et diminue d'autant leur versatilité.

    Mais bon, ce n'est qu'une opinion
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  6. #6
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Partager de l'état, c'est "mal", mais pour la performance c'est parfois nécessaire.

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    192
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 192
    Par défaut
    merci pour vos explications ( que j'ai plus ou moins compris...)

    mais je ne vois pas trop comment faire.
    En gros j'ai deux pointeurs qui pointent vers le meme objet, et je fais un delete sur mes deux pointers.
    Bien sur au deuxieme pointeur ca pante...

    comment indiquer qu'un object est deleted?
    comment savoir qu'un pointer pointe vers qq chose ?

    d'autre conceil ?

  8. #8
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Tu peux peut etre, aussi, envisager de travailler avec quelque chose qui se rapproche du design pattern mediateur (désolé, le lien est en anglais )

    Cela pourrait prendre la forme, simple, 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
    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
    /*L'objet que tu utilise réellement */
    class TonObjet
    {
        /* tout ce qu'il te faut */
    };
    /* par facilité, autant définir un type de tableau :D */
    typedef std::vector<TonObjet*> TabObjet;
    /* déclaration anticipée du médiateur */
    class Mediateur;
    /* la classe au départ de laquelle l'objet est créé/ détruit */
    class CreateurObjet
    {
        public:
            CreateurObjet(Mediateur* med);
            ~CreateurObjet();
            TonObjet* CreeObjet(/* parametres utiles */);
            void DetruitObjet(TonObjet*);
        private:
            Mediateur * med;
    }; 
    /* soit le médiateur contient tous les tableaux d'objet, soit, on peut même
        envisager qu'une classe séparée s'en occupe, sous la forme de */
    class GestionaireTabObjet
    {
        public:
            GestionaireTabObjet( Mediateur* med);
            ~GestionaireTabObjet();
            void AjouteObjet(TonObjet*);
            void ObjetaNUll(TonObjet*);
            const TabObjet& GetTableau() const;
        private: 
            TabObjet tab;
    };
    /* "Tant qu'à faire", un tableau de gestionnaire, c'est pas mal :D */
    typede std::vector<GestionaireTabObjet*> TabGestionnaire
    /* et, enfin, la classe qui communique avec tout cela */
    class Mediateur
    {
        public:
            Mediateur();
            ~Mediateur();
            void AjoutGestionnaire(GestionaireTabObjet*);
            void ObjetCree(TonObjet*);
            void ObjetDetruit(TonObjet*);
        private:
            TabGestionnaire gest;
    };
    Toute création ou destruction d'objet va alors passer par la méthode CreerObjet ou DetruitObjet de la classe CreateurObjet, qui serait implémentée sous la forme de
    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
    CreateurObjet::CreateurObjet(Mediateur* med):med(med)
    { 
        assert(med!=NULL);
    }
    CreateurObjet::~CreateurObjet()
    {
        med=NULL;
    }
    TonObjet* CreateurObjet::CreeObjet(/*les parametres utiles */)
    {
        TonObjet* nouveau=new TonObjet(/* les parametre utiles */);
        med->ObjetCree(nouveau);
        return med;
    }
    void CreateurObjet::DetruitObjet(TonObjet* adet)
    {
        med->ObjetDetruit(adet);
        delete adet;
    }
    et qui s'occupe, en gros, de s'assurer que le médiateur est tenu au courent des constructions/destructions d'objet.

    Le médiateur va se charger de transmettre les créations/destructions d'objet à la classe qui gère le tableau d'objet sous une forme proche de
    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
     
    Mediateur::Mediateur()
    {
     
    }
    Mediateur::~Mediateur()
    {  
        /* j'ai considéré ici que la gestion de la mémoire utilisé par
         * les GestionaireTabObjet est prise en compte ailleurs :D 
         */
    }
    void Mediateur::AjoutGestionnaire(GestionaireTabObjet* toadd)
    {
        /*Idéalement, cette fonction ne devrait être appelée qu'à l'initialisation */
        gest.push_back(toadd);
    }
    void Mediateur::ObjetCree(TonObjet* cree)
    {
        for(size_t i=0;i<gest.size();i++)
           gest[i]->AjouteObjet(cree);
    }
    void Mediateur::ObjetDetruit(TonObjet* detruit)
    {
        for(size_t i=0;i<gest.size();i++)
           gest[i]->ObjetaNull(cree);
    }
    et, enfin, GestionaireTabObjet serait implémenté sous la forme de
    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
    GestionaireTabObjet::GestionaireTabObjet():tab(){}
    GestionaireTabObjet::~GestionaireTabObjet(){}
    const TabObjet& GestionaireTabObjet::GetTableau() const
    {
        return tab;
    }
    void GestionaireTabObjet::AjouteObjet(TonObjet* toadd)
    {
        tab.push_back(toadd);
    }
    void GestionaireTabObjet::ObjetaNUll(TonObjet* torem)
    {
        for(size_t i=0;i<tab.size();i++)
            if(tab[i]== torem)
                tab[i]=NULL;
    }
    NOTA:
    • on pourrait envisager de fournir en parametre les tableaux d'objets auxquels il faut signaler la création de tes objets (pour ce qui est de la destruction, le temps perdu reste négligeable, à moins d'avoir des tableaux réellement immences )
    • Plusieurs optiques sont envisageables au niveau de la persistances des GestionaireTabObjet et du Mediateur... mais là, il manque quelques infos pour en parler
    • *idealement* il faudrait prévoir un système qui s'assure que TonObjet ne puisse être créé/détruit qu'au travers de ObjetCreateur (ea: constructeur/destructeur privé et amitié avec ObjetCreateur)
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    192
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 192
    Par défaut
    Merci pour vos réponses
    merci koala01, j'ai appris plein de trucs.

    je me suis débrouillé pour avoir un truc tout simple, un vector.

    Est ce la fonction erase() de vector suffit bien a supprimer tout les objects contenus dedans, ou faut-il que je fasse un delete sur chaqu'un de mes elements dans une boucle ?

    merci

  10. #10
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Non, il faut effectivement que tu fasse en delete sur tes pointeurs...

    La fonction erase se "contente" de vider le contenu du tableau, mais, comme tu as décidé au départ d'être responsable de la durée de vie des pointeur que le tableau contient, elle te laisse cette responsabilité
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  11. #11
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    mais je ne vois pas trop comment faire.
    En gros j'ai deux pointeurs qui pointent vers le meme objet, et je fais un delete sur mes deux pointers.
    Bien sur au deuxieme pointeur ca pante...
    T'utilises boost::shared_ptr

  12. #12
    screetch
    Invité(e)
    Par défaut
    avoir deux proprietaires sur un objet n'est pas choquant. ce que tu decris plus haut, Emmanuel :
    Selon moi (mais ce n'est qu'un opinion), il est nécessaire de savoir qui est propriétaire de quoi à tout moment. Si deux conteneurs sont propriétaires d'un même objet et que l'un d'eux décide que cet objet doit être détruit, permettre à l'autre conteneur de continuer à l'utiliser est une erreur de logique.
    tu ne partages toujours pas la propriété de l'objet.

    Le vecteur ne peut pas decider de detruire l'objet. il peut selement dire qu'il n'en a plus besoin. si il etait le dernier a l'utiliser, alors l'objet est devenu inutile : il sera detruit.

Discussions similaires

  1. comment savoir si un objet est sélectionné ?
    Par fran.duch dans le forum VBA PowerPoint
    Réponses: 0
    Dernier message: 22/06/2012, 16h01
  2. comment savoir si un objet est itérable ?
    Par DonKnacki dans le forum Collection et Stream
    Réponses: 11
    Dernier message: 25/07/2009, 21h13
  3. [Access] Comment savoir qu'un champs est vide ?
    Par Oberown dans le forum ASP
    Réponses: 9
    Dernier message: 25/10/2004, 10h47
  4. Unix - Comment savoir si un fichier est ouvert
    Par freddyboy dans le forum C
    Réponses: 7
    Dernier message: 06/10/2004, 15h53
  5. Comment savoir qu'une fonction est standard ?
    Par D[r]eadLock dans le forum C
    Réponses: 5
    Dernier message: 24/03/2003, 14h42

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