3 votes

Quel est l'équivalent C++ de C# Collection<T> et comment l'utiliser ?

J'ai besoin de stocker une liste/collection/réseau d'objets créés dynamiquement d'un certain type de base en C++ (et je suis nouveau en C++). En C#, j'utiliserais une collection générique. Que dois-je utiliser en C++ ?

Je sais que je peux utiliser un tableau :

SomeBase* _anArrayOfBase = new SomeBase[max];

Mais je n'obtiens rien de "gratuit" avec cela - en d'autres termes, je ne peux pas itérer dessus, il ne se développe pas automatiquement, etc.

Alors quelles sont les autres options ?

Merci

18voto

Yacoby Points 29771

Il y a std::vecteur qui est une enveloppe autour d'un tableau, mais il peut s'étendre et le fera automatiquement. Cependant, c'est une opération très coûteuse, donc si vous avez l'intention de faire beaucoup d'opérations d'insertion ou de suppression, n'utilisez pas un vecteur. (Vous pouvez utiliser la fonction reserve pour réserver une certaine quantité d'espace).

std::liste est une liste chaînée, dont les temps d'insertion et de retrait sont beaucoup plus rapides, mais l'itération est plus lente car les valeurs ne sont pas stockées dans une mémoire contiguë, ce qui signifie que le calcul des adresses est beaucoup plus complexe et que vous ne pouvez pas tirer parti du cache du processeur lorsque vous itérez sur la liste.
Le principal avantage par rapport au vecteur ou au deque est que les éléments peuvent être ajoutés ou retirés de n'importe quel endroit de la liste à peu de frais.

En guise de compromis, il y a std::deque qui, extérieurement, fonctionne de manière similaire à un vecteur, mais qui, intérieurement, est très différent. Le stockage du deque n'a pas besoin d'être contigu, il peut donc être divisé en blocs, ce qui signifie que lorsque le deque grandit, il n'a pas besoin de réallouer l'espace de stockage pour l'ensemble de son contenu. L'accès est légèrement plus lent et vous ne pouvez pas faire d'arithmétique de pointeur pour obtenir un élément.

9voto

Charles Points 1678

Vous devriez utiliser un vecteur.

#include <vector>

int main()
{
  std::vector<SomeBase*> baseVector;
  baseVector.push_back(new SomeBase());
}

Le C++ contient une collection de conteneurs de données au sein de la STL. Consultez-le aquí .

4voto

Nikola Smiljanić Points 15585

Vous devez utiliser l'un des conteneurs

std::vector<SomeBase>
std::list<SomeBase>

et si vous avez vraiment besoin d'objets alloués dynamiquement

std::vector<boost::shared_ptr<SomeBase>>
std::list<boost::shared_ptr<SomeBase>>

2voto

Chris Pitman Points 5981

Tout le monde a mentionné que les contrôles communs SC++L, mais il y a une autre mise en garde importante lorsque l'on fait cela en C++ (que Chaoz a incluse dans son exemple ).

En C++, votre collection devra être modélisée sur SomeBase* , no sur SomeBase. Si vous essayez d'assigner une instance du type dérivé à une instance du type de base, vous finirez par provoquer ce que l'on appelle un "accident". découpage d'objets . Ce n'est certainement pas ce que vous essayez de faire.

Puisque vous venez du C#, rappelez-vous que " SomeBase MyInstance "signifie quelque chose de très différent dans les deux langues. L'équivalent en C++ est généralement " SomeBase* MyPointer " ou " SomeBase& MyReference ".

1voto

CesarGon Points 8710

Utilisez un vector . Jetez un coup d'œil aquí .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X