9
votes

Supprimer tout conteneur à l'aide de modèles

J'ai beaucoup de code où je supprimons des conteneurs de vecteur qui ont des pointeurs d'eux, c'est-à-dire que je dois supprimer tous les pointeurs d'abord, puis effacer le conteneur. Chaque fois que je voudrais parcourir et supprimer les pointeurs manuellement (je suis au courant de STL :: algorithmes pour_ach). Pour contourner tout ce code, j'ai créé un modèle pour supprimer tous les conteneurs de vecteur qui ont un pointeur. Jusqu'à présent, si bon.

Maintenant, j'ai plusieurs types de conteneurs, notamment des cartes, des conteneurs simultanés, etc. Tous avec la même fonctionnalité à la fin, jusqu'à la suppression. Le deletecontainer (std :: vecteur & veecin) la fonction que j'ai ne peut que travailler sur des vecteurs comme mentionné ci-dessus. Y a-t-il un moyen de le rendre assez générique pour travailler sur tous les conteneurs?

EDIT: Merci pour toutes les réponses, j'aimerais pouvoir choisir plus d'un. À quiconque qui trébuche sur cette question, lisez toutes les réponses et non seulement la sélection sélectionnée, car elles fournissent tous de superbes informations.


0 commentaires

7 Réponses :


3
votes

Vous pouvez simplement utiliser boost :: Shared_ptr code> insté de t * code> et il n'y aura pas de raison de Supprenontainer code>. Mais si vous ne voulez pas faire cela, vous pouvez faire quelque chose comme ça

std::some_container<int*> s;
DeleteContainer<std::some_container<int*> > (s.begin(), s.end());


2 commentaires

Ce n'est pas très c ++ ish. Le conteneur n'est pas sûr de l'exception car vous appelez manuellement le Delier. Vous devez envelopper le conteneur dans l'objet AB afin que RAII appelle en réalité la fonction automatiquement lorsque le conteneur est hors de portée.


Même commentaire que l'autre réponse, vous devez gérer différemment des conteneurs associatifs.



7
votes

Vous avez déjà une réponse valide, mais simplement pour fournir une alternative, je pense que vous devriez envisager d'utiliser Boost Pointeur conteneur et laissez-le gérer la gestion de la mémoire:

Cette bibliothèque fournit donc conteneurs ressemblant à des normes qui sont pour stocker le tas alloué ou cloné objets (ou en cas de carte, le objet mappé doit être alloué à un tas ou objet cloné). pour chacun des conteneurs standard il y a un pointeur équivalent de conteneur qui prend propriété des objets dans un de manière sûre d'exception.


0 commentaires

4
votes

Vous pouvez utiliser des conteneurs de pointeur Boost.
Ils détiennent de maintenir et de supprimer correctement les pointeurs.

http: //www.boost.org/doc/libs/1_38_0/libs/ptr_container/doc/reference.html xxx


0 commentaires

4
votes

Je vais reculer de plusieurs personnes et aviser à l'aide de Shared_PTR ou BOOST POINTER CONTENANTS. Cependant, vous pouvez écrire xxx

usage: xxx

i utilise rbegin et rendu au lieu de commencer et fin (code> finalement car parfois, les gens veulent que des objets soient supprimés dans l'ordre inverse, ils ont été créés.

Vous pouvez aussi faire < / p> xxx

ou utilisez C ++ 0x lambdas.


5 commentaires

Le seul commentaire que j'ajouterais est que vous devez gérer différemment des conteneurs associatifs, comme vous ne pouvez pas appeler supprimer sur la paire .


@Nim: très bon point. Vous ne pouvez pas facilement itération sur des clés ou des valeurs facilement avec des cartes C ++, vous devez écrire un adaptateur "second_iterator".


Will :: L'opérateur Supprimer simplement annoncer la mémoire ou cela appellera-t-il aussi le destructeur? J'ai mes doutes ici ...


@Tomek: Pour être honnête, j'ai aussi des doutes.


Je suis à peu près sûr que «l'opérateur Supprimer» est fondamentalement C ++ 'S' GRATUITEMENT ', afin que les dtors ne soient pas appelés. 5.3.5 / 6 fait référence à "Supprimer-expression" invoquant le destructeur, puis 5.3.5 / 7 indique que "l'expression de suppression appellera une fonction de transaction". Et "Opérateur Supprimer" est l'une des fonctions de distribution. Mais comme avec la plupart des réponses ici, ils oublient tous les cas supprimés [].



0
votes

Une alternative consiste à abandonner les choses entièrement et à s'engager à utiliser un collecteur de déchets :) Vous pouvez essayer le collecteur BoehM-Reiser-Detlefs, il est standard sur Linux (Libgc) et il est utilisé dans de nombreux programmes complexes maintenant. (tels que GCC). C'est aussi une bonne idée d'abandonner Raii: c'était une bonne idée à ce moment-là, mais cela ne fonctionne pas si bien dans la pratique. De nombreuses ressources sont créées et détruites indépendamment de l'ordre avec leur représentation.


0 commentaires

0
votes

Mon principe sur ce serait: xxx

testé sur g ++ 4.4.4 avec vector, drique et liste. Vous aurez peut-être besoin de surcharges supplémentaires de détruire vides (C & C) pour d'autres conteneurs et / ou d'autres implémentations STL.


1 commentaires

Cela ne gère pas le cas de STD :: Certain_container . Depuis, quelque_container est plus souvent utilisé que quelque_container , il vaut mieux gérer le cas de char *.



1
votes

Comme suggéré par Tomek, nous pouvons avoir une solution similaire pour gérer la suppression. Une structure aurait été meilleure qu'une fonction libre.

struct Delete
{
   public:
      template<typename T>
      void operator()(const T* ptr) const
      {
          delete ptr;
      }
      void operator()(const char* ptr) const
      {
          delete[] ptr;

     }
};


1 commentaires

Pourquoi est-ce meilleur qu'une fonction libre?