J’ai personnellement presque jamais vu un moment où utiliser un std::shared_ptr
était un bon choix.
La première question à se poser, c’est en quoi utiliser un vecteur de pointeur va optimiser ton programme? Sans plus de contexte, j’aurais tendance à dire que ça va plutôt empirer les choses puisque tes accès mémoire seront bien moins prédictibles, ce qui augmentera certainement les chances de défaut de cache. Ça ne va clairement pas optimiser les choses.
Tu parles d’éviter des copies, j’en conclue donc que ton objet Equipement est probablement d’une taille significative et que tes instances sont baladés d’un conteneur à un autre. Si c’est bien le cas, utiliser des pointeurs est en effet une bonne idée.
Comme l’a fait remarqué d3m0t3p, utiliser des pointeurs intelligents est plus pratique. En revanche, à moins que tu veuilles qu’un équipement puisse être contenu dans plusieurs conteneurs à la fois, utiliser std::unique_ptr
est plus performant et sémantiquement plus correct.
Ça s’utilise plus ou moins comme un std::shared_ptr
, en un peu plus compliqué. Globalement, lorsque tu veux bouger un std::unique_ptr
d’un endroit à un autre, tu ne peux pas simplement le copier et supprimer l’ancienne version, tu dois bouger le pointeur avec std::move
:
1
2
3
4
5
6
7
8
9
10
11
12
13 | // Initialisation du premier conteneur (origine)
std::vector<std::unique_ptr<int>> vecteur1;
vecteur1.emplace_back(new int(1));
vecteur1.emplace_back(new int(2));
// Initialisation du deuxième conteneur (destination)
std::vector<std::unique_ptr<int>> vecteur2;
// Déplacement du premier élément de vecteur1 dans vecteur2
vecteur2.emplace_back(std::move(vecteur1[0]));
// vecteur2 contiens maintenant 1 et le premier élément de vecteur1 est un pointeur null.
// Il faut donc maintenant le retirer:
vecteur1.erase(vecteur1.begin());
|
Si avoir des pointeurs vide dans ton équipement ne te dérange pas (par exemple, si ton équipement a une taille fixe où les pointeurs null sont des emplacements vide), tu peux te contenter d’utiliser std::swap
pour échanger deux éléments:
| std::array<int, 5> petit_array;
std::array<int, 20> grand_array;
// On met quelques éléments dans petit_array
petit_array[0] = std::make_unique<int>(42);
petit_array[2] = std::make_unique<int>(1000);
// On déplace le premier élément de petit_array à la fin de grand_array
std::swap(petit_array[0], grand_array[19]);
|