2009-12-06 1 views
3

J'ai besoin de stocker une liste/collection/tableau 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++?Quel est l'équivalent C++ de C# Collection <T> et comment l'utilisez-vous?

Je sais que je peux utiliser un tableau:

SomeBase* _anArrayOfBase = new SomeBase[max]; 

Mais je ne reçois rien « gratuitement » à ce sujet - en d'autres termes, je ne peux pas itérer, il ne se développe pas automatiquement et ainsi de suite.

Alors, quelles sont les autres options?

Merci

+0

En fait, vous pouvez itérer sur un tableau. L'itérateur de départ est '_anArrayOfBase', et l'itérateur de fin est' _anArrayOfBase + max', ce qui est tout ce dont vous avez besoin pour l'itération de style C++. Mais vous avez absolument raison à propos de l'expansion. –

Répondre

17

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

est une liste chaînée qui a des temps d'insertion et de suppression beaucoup plus rapides, mais l'itération est plus lente car les valeurs ne sont pas stockées dans la mémoire contiguë, laquelle signifie que le calcul d'adresse est beaucoup plus complexe et que vous ne pouvez pas tirer parti du cache des processeurs lors de l'itération sur la liste.
Le principal avantage par rapport au vecteur ou au deque est que les éléments peuvent être ajoutés ou supprimés de n'importe où dans la liste à un coût relativement bas.

En guise de compromis, il existe std::deque, qui fonctionne de manière similaire à un vecteur, mais en interne, ils sont très différents. Le stockage de deque ne doit pas être contigu, il peut donc être divisé en blocs, ce qui signifie que lorsque la deque se développe, il n'a pas besoin de réaffecter 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.

4

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>> 
0

Utilisez STL. std :: vector et std :: set par exemple. Beaucoup d'exemples là-bas.

9

Vous devez utiliser un vecteur.

#include <vector> 

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

C++ contient une collection de conteneurs de données dans la STL. Check it out here.

1

Je suis un grand fan de std :: deque. Si vous voulez des choses gratuitement, le deque vous les donne. Accès rapide depuis la tête et la queue de la liste. itérateurs, reverse_iterators, insertion rapide en tête et en queue. Ce n'est pas super spécialisé, mais vous vouliez des trucs gratuits. ;-)

Aussi, je vais lier une grande référence STL. Le STL est où vous obtenez tous les trucs "gratuits" standard en C++. Standard Template Library. Prendre plaisir!

2

Tout le monde a mentionné que les contrôles SC++ L communs, mais il ya une autre mise en garde importante en faisant cela en C++ (que Chaoz a inclus dans his example).

En C++, votre collection devra être modélisée sur SomeBase*, et non sur SomeBase. Si vous essayez d'affecter une instance du type dérivé à une instance du type de base, vous finirez par provoquer ce que l'on appelle object slicing. C'est presque certainement pas ce que vous essayez de faire.

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