C ++ Deux dimensions std :: meilleures pratiques vectorielles
Je suis la création d'une application qui a besoin d'un support pour les deux dimensions des tableaux de tenir une grille de données. J'ai une classe Map
qui contient une grille 2d de données. Je veux utiliser des vecteurs plutôt que les tableaux, et je me demandais quelles sont les meilleures pratiques pour l'utilisation de vecteurs 2d. Si j'ai un vecteur de vecteurs de MapCells? ou devrait-il être un vecteur de vecteurs de pointeurs pour MapCells? ou des références à d'MapCells?
class Map {
private:
vector<vector<MapCell>> cells;
public:
void loadMap() {
cells.clear();
for (int i = 0; i < WIDTH; i++) {
//How should I be allocating these?
vector<MapCell> row(HEIGHT);
for (int j = 0; j < HEIGHT; j++) {
//Should I be dynamically allocating these?
MapCell cell;
row.push_back(cell);
}
cells.push_back(row);
}
}
}
Fondamentalement, ce que cela va me faire le moins de problèmes (à l'égard de la gestion de la mémoire ou quoi que ce soit d'autre)?
source d'informationauteur goatlinks
Vous devez vous connecter pour publier un commentaire.
Lorsque vous voulez un carré ou une grille 2d, faire quelque chose de semblable à ce que le compilateur ne pour les tableaux multidimensionnels (les vrais, pas un tableau de pointeurs de tableaux) et de stocker un seul grand tableau qui vous index correctement.
Exemple à l'aide de la Matrice de classe ci-dessous:
Variantes de la matrice des classes abondent, et il existe de nombreuses façons d'adapter pour une utilisation spécifique. Voici un exemple, en moins de 100 lignes que vous obtient plus de 80% de ce que vous avez besoin de:
Si l'ensemble de la matrice est généralement constante la largeur et la hauteur, vous pouvez aussi bien utiliser une seule
vector
et l'adresse des cellules avec(row * columnCount) + column
. De cette façon, le tout sera stocké dans un seul bloc de mémoire au lieu de plusieurs blocs fragmentés pour chaque ligne. (Bien sûr, vous faites la bonne chose à envelopper ce concept dans une nouvelle classe - je suis juste de parler de la derrière-le-scènes de la mise en œuvre.)Un vecteur de vecteurs a la fâcheuse propriété que si vous insérez une ligne en haut,
std::vector
va effectuer une copie de construction (ou de la cession, peut-être) pour toutes les autres lignes comme il se déplace vers le bas en un seul endroit. Ce à son tour, implique la répartition de la de stockage pour chaque ligne individuellement et de copier les éléments dans les cellules de chaque ligne. (C++0x sera probablement mieux à ce niveau.)Si vous savez que vous allez être faire ce genre de chose souvent, l'avantage d'un seul grand bloc de mémoire, c'est que vous pouvez insérer une nouvelle ligne au dessus et
std::vector
n'aurez qu'à changer toutes les cellules de l'avant parcolumnCount
endroits, donc il va sérieusement réduire le nombre d'opérations segment (libération/la réaffectation des blocs individuels).Bien que, comme vous le suggérez, un vecteur de pointeurs sur des vecteurs aurait en outre l'avantage qu'il aurait seulement besoin de les déplacer vers l'avant beaucoup de valeurs de pointeur, et la taille du bloc contenant tous les pointeurs seront beaucoup plus petits, en plus de diminuer l'impact des opérations segment.
Bien sûr, la seule façon d'être sûr de l'impact réel de ces choses sur les performances d'une application est à la fois avec les différentes implémentations et de les comparer. C'est pourquoi vous êtes en train de faire exactement la bonne chose en cachant ces détails à l'intérieur d'une nouvelle classe.
Utilisation d'un vecteur et de traduire les 2 dimensions à une dimension.
E. g. si votre matrice a une largeur W et de hauteur H, puis de cartographie x,y à l'index dans le vecteur est tout simplement x*W+y.
Si votre matrice est clairsemée, vous souhaiterez peut-être utiliser un std::map où la clé est une paire (x et y).
Dans mes projets, j'utilise souvent cette simple classe de la grille.