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 :

Pointeurs : destruction / concaténation


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Avril 2014
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2014
    Messages : 35
    Par défaut Pointeurs : destruction / concaténation
    Bonjour,

    j'ai un vecteur qui contient des pointeurs pointant sur des objets d'une class "truc" que j'ai créé.

    Ma première question est concernant la concaténation. Est-il possible d'une manière rapide et efficace de concaténer deux vecteurs de telle façon que les pointeurs qui pointent sur le même objet ne se retrouvent pas en "double" ? Est-ce que cela existe déjà ou je dois créer une fonction moi-même ? En gros si vecteur A et vecteur B tous les deux contient un pointeur sur le même objet, il n'y aura pas deux pointeurs dans le vecteur concaténé.

    Deuxième question concerne la destruction. Je voudrais pouvoir fusionner deux objets de ma class "truc". Pour cela je voudrais mettre les attributs du second objet dans le premier (pas de problème) et supprimer le second objet. Pour supprimer le second objet je pense qu'il faut que j'utilise le destructeur de copie. Mais dans ce cas la, qu'adviendra-t-il de mes pointeurs sur les objets détruits ? Seront-ils toujours dans mon vecteur de pointeur ? Est-ce qu'il y a moyen de détruire automatiquement les pointeurs qui pointent sur des objets "détruits" ?

    Merci !

  2. #2
    Expert confirmé

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 033
    Billets dans le blog
    12
    Par défaut
    Pour ton premier problème, tu peux envisager plusieurs méthodes :
    - Utilisation de std::set => Eléments uniques triés
    - Utilisation de std::unordered_set => Eléments uniques non triés (plus adapté aux pointeurs)
    - Utilisation de std::vector/list + std::unique + std::remove => Solution par défaut, qui marche mais pas la plus adaptée.

    Pour ton cas je partirais sur un std::unordered_set.


    Pour ton second problème, les std::shared_ptr résoudront ton soucis.
    Par contre je te conseille de faire attention à la responsabilité (qui crée le pointeur, qui le détruit) pour savoir exactement quel est ton besoin.
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  3. #3
    Membre averti
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Avril 2014
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2014
    Messages : 35
    Par défaut
    Salut, merci beaucoup pour ta réponse,

    concernant les shared_ptr j'ai regardé la documentation et je ne suis pas persuadé que cela résolve mon problême (ou problablement j'ai mal compris le truc...). De ce que j'ai compris les shared_ptr permettent de créer plusieurs pointeurs qui partagent la propriété de l'objet avec un compteur du nombre de pointeurs pointant sur l'objet et donc l'objet ne sera détruit que lorsque tous les pointeurs seront détruit.

    Moi ce que je veux faire c'est détruire "manuellement" l'objet et automatiquement détruire tous les pointeurs qui pointaient sur l'objet. En fait pour expliquer vraiment, j'ai une classe "Zone" avec des attributs ainsi qu'un vecteur de pointeurs pointant sur des autres objets de classe "Zone" qui sont les voisins d'une zone donnée. En gros chaque zone a un vecteur d'une dizaine de pointeurs pointant sur ses voisins. Je voudrais pouvoir détruire un objet de class zone et automatiquement tous les pointeurs qui sont dans les vecteurs de ses voisins soient détruit (de telle façon qu'il ne reste pas de vecteur avec des pointeurs qui ne pointent sur rien du tout).

    Est-ce que shared_ptr permet cela ? (désolé si c'est le cas et j'ai mal compris le principe ...)

    Aussi, serait-il possible / plus performant / plus logique de procéder par référence plutot que par pointeur pour l'example ci-dessus ? J'ai du mal a voir la différence entre les deux.

    Merci beaucoup pour ton aide.

  4. #4
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 760
    Par défaut
    Tu as eu la moitié de l'histoire

    Il y a les shared_ptr et les weak_ptr.
    Plus l'usine: make_shared

    C'est pour cela que dragonjoker59 te dit de "faire attention à la responsabilité (qui crée le pointeur, qui le détruit) pour savoir exactement quel est ton besoin"

  5. #5
    Membre Expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Par défaut
    Salut

    Citation Envoyé par dragonjoker59 Voir le message
    Pour ton premier problème, tu peux envisager plusieurs méthodes :
    - Utilisation de std::set => Eléments uniques triés
    - Utilisation de std::unordered_set => Eléments uniques non triés (plus adapté aux pointeurs)
    - Utilisation de std::vector/list + std::unique + std::remove => Solution par défaut, qui marche mais pas la plus adaptée.

    Pour ton cas je partirais sur un std::unordered_set.
    Ces méthodes sont toutes valides. Cependant, je n'irais pas jusqu'à me prononcer sur le choix à faire, car on n'a pas assez d'informations sur ton utilisation pour savoir ce qui est le plus adapté. Par exemple, std::set et std::unordered_set sont mauvais pour l'accès aléatoire (accès par l'indicie de l'élément, et par extension, accès par parcours de tous les éléments). Du coup, si ton algo a plus tendance à parcourir tes collections et que les insertions/fusions sont moins fréquentes que les lectures, il vaut peut-être mieux garder std::vector qui est imbattable sur l'accès aléatoire. Un "sorted vector" (un vecteur que tu maintiens trié en l'encapsulant dans un objet supérieur) peut aussi être une alternative très intéressante si tu as besoin à la fois d'un accès aléatoire et d'un accès par la clé (la clé ici étant le pointeur de l'objet).

    Si tu as un doute, la meilleure manière d'arbitrer reste d'implémenter les deux techniques entre lesquelles tu hésites et de faire un test de performances.

    Citation Envoyé par StingerBell Voir le message
    Je voudrais pouvoir détruire un objet de class zone et automatiquement tous les pointeurs qui sont dans les vecteurs de ses voisins soient détruit (de telle façon qu'il ne reste pas de vecteur avec des pointeurs qui ne pointent sur rien du tout).

    Est-ce que shared_ptr permet cela ? (désolé si c'est le cas et j'ai mal compris le principe ...)
    En effet, en utilisant shared_ptr::reset() et weak_ptr, tu peux obtenir cette fonctionnalité. Mais j'attire ton attention sur plusieurs choses:
    - shared_ptr est coûteux, car il est fait pour que l'accès concurrent à un objet via plusieurs threads (et un shared_ptr par thread, ou plus) soit safe. De fait, si tu n'as qu'un thread, tu vas payer pour quelque chose que tu n'utilises pas.
    - Cette technique impose de stocker au moins un shared_ptr quelque part et des weak_ptr ailleurs. Peut-être que ton algo n'est pas pensé comme ça et va mal s'adapter à cet état de fait.
    - Si tu invalides une série que weak_ptr en détruisant le shared_ptr "maître", les weak_ptr restants seront toujours dans les collections (vector ou autre, selon le choix fait dans la première partie). Ca peut être intéressant si tu fais un nettoyage "différé", c'est à dire
    si tu profites d'un parcours de la collection qui a un autre but pour trouver les références invalides et les nettoyer, ok. Mais peut-être que tu voudras nettoyer les collections des pointeurs invalides dès la destruction effectuée, dans lequel cas, shared_ptr ne te rendra pas un bien grand service.

    Sinon à propos des références, je t'avoue que j'ai un peu la flemme de coucher l'explication classique ici (Koala01, tu veux pas ?), la FAQ devrait te renseigner assez sur le sujet. Des collections de références, ça ne se fait pas trop. A la limite, des collections de reference_wrapper, oui, pourquoi pas, j'ai déjà fait ça.

  6. #6
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    vector est généralement le moins mauvais choix par défaut. Commencer par vector puis voir si on peut faire mieux est préférable que l'inverse.

    Par contre,
    Citation Envoyé par jblecanard Voir le message
    Par exemple, std::set et std::unordered_set sont mauvais pour l'accès aléatoire (accès par l'indicie de l'élément, et par extension, accès par parcours de tous les éléments).
    Qu'entends-tu par accès par parcours ?
    Dans tous les cas, parcourir n'importe quelle collection par un itérateur de begin à end est (quasi) gratos. Et c'est le mieux à faire dans ce cas, pour pouvoir changer de collection sans modifier le parcours.
    Les itérateurs sont très doués pour leur operator++

    Citation Envoyé par jblecanard Voir le message
    Du coup, si ton algo a plus tendance à parcourir tes collections et que les insertions/fusions sont moins fréquentes que les lectures, il vaut peut-être mieux garder std::vector qui est imbattable sur l'accès aléatoire.
    Idem, ça dépend de la façon de parcourir.
    Si les parcours se font toujours du début à la fin, ou à partir d'un élément gardé en mémoire, et que les ajouts sont fréquents, la list est un excellent compromis. A la concession de l'accès aléatoire.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

Discussions similaires

  1. Destruction d'un pointeur
    Par julieng31 dans le forum Débuter
    Réponses: 2
    Dernier message: 29/01/2009, 21h01
  2. Réponses: 3
    Dernier message: 25/11/2008, 15h52
  3. probleme de destruction de pointeur
    Par Dom_the_quaker dans le forum C++
    Réponses: 6
    Dernier message: 09/06/2008, 17h05
  4. Algorithme de concaténation à partir de pointeurs
    Par sundering dans le forum C++
    Réponses: 3
    Dernier message: 29/01/2008, 21h55
  5. pointeur et destruction
    Par darkfrag dans le forum C++
    Réponses: 7
    Dernier message: 19/05/2007, 15h41

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