Je me demandais simplement ce que vous pensez être la meilleure pratique des vecteurs en C ++.
Si j'ai une classe contenant une variable de membre vectoriel. Quand ce vecteur devrait-il être déclaré: p>
vecteur * my_vector; code> li>
- Vecteur des pointeurs, c'est-à-dire
vecteur my_vector; code> li>
- Pointeur au vecteur des pointeurs, c'est-à-dire
vecteur * my_vector; code> li>
ol> J'ai un exemple spécifique dans l'une de mes classes où j'ai actuellement déclaré un vecteur comme cas 4, i.e. vecteur * my_vector; code>
où une autreclass est une autre des classes que j'ai créées. p> Puis, dans la liste d'initialisation de mon constructeur, je crée le vecteur en utilisant non: p> xxx pré> Dans mon destructeur, je fais ce qui suit: p> xxx pré> Les éléments des vecteurs sont ajoutés dans l'une des méthodes de ma classe.
Je ne sais pas combien d'objets seront ajoutés à mon vecteur à l'avance. Cela est décidé lorsque le code exécute, basé sur l'analyse d'un fichier XML. P>
est cette bonne pratique? Ou si le vecteur devrait plutôt être déclaré comme l'un des autres cas 1, 2 ou 3? P>
Quand utiliser quel cas? P>
Je sais que les éléments d'un vecteur doivent être des pointeurs si Ce sont des sous-classes d'une autre classe (polymorphisme). Mais les pointeurs doivent-ils être utilisés dans tous les autres cas? P>
Merci beaucoup !! p> p>
6 Réponses :
Un pointeur sur un pour des éléments dans le vecteur code> code>, il n'y a pas de réponse correcte. À quelle fréquence le En règle générale, j'irais sans pointe avant de voir voir em> ou mesurer em> que la copie de vos classes coûte cher. Et bien sûr, le cas que vous avez mentionné, où vous stockez divers sous-classes d'une classe de base dans le vecteur code> code>, nécessitera des pointeurs. P>
Un comptage de référence Smart Pointer comme vecteur code> est très rarement utile - un
vecteur code> est bon marché pour construire et détruire. p>
vecteur code> change-t-il? Combien cela coûte-t-il de copier-construire les éléments dans le vecteur code> code>? Les autres conteneurs ont-ils des références ou des pointeurs sur le vecteur code> code> p>
Boost :: partagé_ptr code> sera probablement le meilleur choix si votre conception vous demanderait d'utiliser des pointeurs comme
vecteur p >
Donc, dans mon exemple, si autreclass i> est une grande classe avec beaucoup de variables de membre, il pourrait être une bonne idée de stocker ces éléments comme des pointeurs du vecteur? Éviter de copier de gros objets.
@Lisa: Exactement. La bonne réponse ne peut être rien que "cela dépend".
Pouvez-vous élaborer sur le premier point - "Un pointeur à un vecteur est très rarement utile - un vecteur est bon marché pour construire et détruire." Comment?
Habituellement Solution 1 est ce que vous voulez car c'est le plus simple en C ++: vous n'avez pas à vous occuper de la gestion de la mémoire, C ++ fait tout cela pour vous (par exemple, vous n'avez pas besoin de fournir à aucun destructeur alors). . p>
Il existe des cas spécifiques dans lesquels cela ne fonctionne pas (le plus notamment lorsque vous travaillez avec des objets polymorphes) mais en général c'est le seul bon sens. P>
même lorsque vous travaillez avec des objets polymorphes ou lorsque vous avez besoin d'objets alloués en tas (pour une raison quelconque) Les pointeurs bruts sont presque jamais em> une bonne idée. Utilisez plutôt un pointeur intelligent ou un conteneur de pointeurs intelligents. Compilateurs modernes C ++ fournissent partagé_ptr code> à partir de la norme C ++ à venir. Si vous utilisez un compilateur qui n'aura pas encore cela, vous pouvez utiliser le Mise en œuvre de Boost . P>
Je me demande pourquoi les gens ne mentionnent jamais boost.Poinger conteneur code> ou
boost.reference code> dans ce contexte.
@Space j'ai, de la sorte: "Utilisez un pointeur intelligent ou un conteneur de pointeurs intelligents i>." Je ne les ai jamais utilisées, alors je ne me sens pas très confiant de parler de leurs avantages.
@Konrad: "... Les pointeurs bruts (dans des conteneurs) ne sont presque jamais une bonne idée". Juste curieux - en plus de l'aspect (manuel) de la gestion de la mémoire de l'utilisation d'un pointeur brut dans des conteneurs, il y a d'autres raisons pour n'utiliser pas les pointeurs bruts dans un conteneur? Je me souviens vaguement là-bas étant une raison sur les lignes de: "En tant que conteneurs (disons un vecteur), croître / rétrécit, ils peuvent allouer / traiter / copier / déplacer leur contenu pouvant causer des problèmes / effets secondaires indésirables si leur contenu est des pointeurs cru aux objets versus disent un partage_ptr aux objets. " Est-ce précis / correct?
@Decimus n'est pas assez d'une raison? Je ne pense pas que la raison pour laquelle vous avez mentionnée est entièrement exacte. Les pointeurs eux-mêmes peuvent être copiés et déplacés sans aucun problème. Cela ne devient délicat que lorsque l'objet doit gérer i> ces pointeurs depuis lors, vous devez fournir une sémantique appropriée de la copie et des attributions.
Par exemple, vous n'avez pas besoin de fournir aucun destructeur, alors code> est-ce correct? Le vecteur lui-même n'est pas supprimé, auquel cas vous aurez une fuite de mémoire. Vous devriez toujours faire un destructeur et dire
Supprimer TheVector code>
@Veryone c'est incorrect. Vous ne pouvez supprimer que des pointeurs et vous ne devez supprimer que des pointeurs dont le pointe a été attribué par nouveau code>. Un vecteur n'est pas un pointeur alors rien de tout cela ne s'applique ici.
@Konradrudolph désolé je pensais que vous parliez de celui-ci vecteur
Suppression manuelle de tous les éléments d'un vecteur est un anti-motif et enfreint l'idiome Raii en C ++. Donc, si vous devez stocker des pointeurs vers des objets dans un Il n'y a pas non plus besoin d'allouer supposant Dans de nombreux cas, vous pouvez même utiliser un clair vecteur code>, mieux utiliser un «pointeur intelligent» (par exemple
boost :: Shared_ptr code>) pour faciliter la destruction des ressources.
Boost :: Shared_Ptr Code> Par exemple Appels
Supprimer CODE> automatiquement lorsque la dernière référence à un objet est détruite.
myClass :: my_vector code> en utilisant
nouveau code>. Une solution simple serait: p>
quel que soit code> est un type de pointeur intelligent, il y a aucun travail supplémentaire à faire em >. C'est tout, toutes les ressources sont automatiquement détruites lorsque la durée de vie d'un
MyClass CODE> instance se termine. P>
std :: vecteur
Lorsque vous dites "Supprimer tous les éléments dans un vecteur manuellement" voulez-vous dire pas b> dans le destructeur? De wikipedia lien ".. et libéré avec la destruction des mêmes objets, garantie avoir lieu même en cas d'erreur. " Cela signifie-t-il si vous supprimez des éléments dans un vecteur avec le conducteur, vous ne violez pas Raii?
définitivement le premier! p>
Vous utilisez le vecteur pour sa gestion automatique de la mémoire. Utiliser un pointeur brut sur un vecteur signifie que vous n'obtenez plus la gestion automatique de la mémoire, ce qui n'a pas de sens. P>
Quant au type de valeur: Tous les conteneurs assument essentiellement une sémantique de valeur. Encore une fois, vous devez effectuer une gestion de la mémoire lorsque vous utilisez des pointeurs et que le vecteur est de le faire pour vous. Ceci est également décrit dans le point 79 du livre Normes de codage C ++ . Si vous devez utiliser la propriété partagée ou des liens «faibles», utilisez plutôt le pointeur intelligent approprié. P>
Dans votre exemple, le vecteur est créé lorsque l'objet est créé et qu'il est détruit lorsque l'objet est détruit. C'est exactement le comportement que vous obtenez lorsque vous faites le En outre, dans votre approche actuelle, vous rencontrerez des problèmes lors de la copie de votre objet. Par défaut, un pointeur entraînerait une copie à plat, ce qui signifie que toutes les copies de l'objet partagent le même vecteur. C'est la raison pour laquelle, si vous gérez manuellement des ressources, vous avez généralement besoin The Big Trois a>. p>
Un vecteur des pointeurs est utile en cas d'objets polymorphes, mais il y a des alternatives que vous devriez envisager: P>
vecteur code> un membre normal de la classe. p>
boost :: ptr_vector code>
. li>
boost :: partage_ptr code>
ou un vecteur de boost :: ref code>
. li>
ol>
Réponse complexe: Cela dépend. P>
Si votre vecteur est partagé ou a un cycle de vie différent de la classe qui l'incorpore, il peut être préférable de le garder comme un pointeur. Si les objets que vous référencez n'ont pas de constructeurs de copies (ni coûteux), il est préférable de garder un vecteur de pointeur. Au contraire, si vos objets utilisent une copie peu profonde, l'utilisation de vecteur d'objets vous empêche de fuir ... p>