HOWTO · C++
Accéder aux fonctions des membres depuis un pointeur jusqu'à un vecteur en C++
Découvrez comment appeler les membres de std::vector via un pointeur en C++, passer le pointeur du vecteur à une fonction et parcourir ses éléments.
Sur cette page
Pour appeler un membre d’un vecteur C++ à travers un pointeur, utilisez ptr->member ; la forme équivalente est (*ptr).member. Le pointeur doit désigner l’objet vecteur lui-même. Prenez l’adresse de cet objet avec &, puis utilisez l’une ou l’autre expression pour accéder à des membres tels que size() et at(). L’exemple ci-dessous montre également comment transmettre le pointeur à une fonction et lire chaque valeur à travers lui.
Utiliser -> pour accéder à un vecteur à travers un pointeur
Déclarez un pointeur en faisant suivre le type du vecteur de *. Pour un vecteur d’entiers, ce type est std::vector<int>*. Si values est un vecteur existant, &values en donne l’adresse ; l’affecter au pointeur fait donc pointer celui-ci vers le vecteur. Cela ne copie pas le vecteur et ne crée pas une collection distincte.
L’opérateur flèche combine le déréférencement du pointeur et la sélection d’un membre. Ainsi, ptr->size() appelle size() sur le vecteur désigné par ptr. Vous pouvez transmettre ce même pointeur à une fonction dont le paramètre a un type de pointeur correspondant. Dans l’exemple complet, report_size reçoit un pointeur vers un vecteur constant, car la fonction ne fait que le lire. La qualification const empêche la fonction de modifier le vecteur à travers son paramètre ; elle ne change pas la manière de transmettre le pointeur.
Exécutez cet exemple :
#include <cstddef>
#include <iostream>
#include <vector>
void report_size(const std::vector<int>* ptr) {
std::cout << "Count: " << ptr->size() << '\n';
}
int main() {
std::vector<int> values{10, 20, 30};
const std::vector<int>* ptr = &values;
report_size(ptr);
for (std::size_t i = 0; i < ptr->size(); ++i) {
std::cout << (*ptr).at(i) << '\n';
}
}
Count: 3
10
20
30
L’exécution affiche la taille du vecteur, puis chaque valeur sur sa propre ligne. Le vecteur est une variable locale automatique, et le pointeur n’est utilisé que tant que ce vecteur reste dans sa portée. Dans votre programme, veillez à ce qu’un pointeur ne survive pas à l’objet dont il contient l’adresse.
Utiliser (*ptr).member pour accéder à un vecteur à travers un pointeur
L’expression (*ptr).member déréférence d’abord ptr, ce qui donne l’objet vecteur, puis sélectionne l’un de ses membres avec .. Les parenthèses sont nécessaires : sans elles, l’opérateur point s’appliquerait à ptr avant le déréférencement, ce qui n’est pas l’opération voulue. Pour un membre du vecteur, (*ptr).size() et ptr->size() ont le même sens. La forme avec la flèche est plus courte ; celle avec le déréférencement et le point rend explicites les deux opérations.
Dans l’exemple ci-dessus, (*ptr).at(i) accède à un élément par son indice après avoir déréférencé le pointeur vers le vecteur. L’appel de membre s’effectue toujours sur le vecteur, tandis que at(i) renvoie l’entier sélectionné. Cette distinction est utile pour lire le code : ptr est de type pointeur vers un vecteur, mais (*ptr).at(i) désigne une valeur d’élément. Si une fonction doit travailler avec le vecteur, transmettez un pointeur vers celui-ci ; si elle doit travailler avec un seul élément, utilisez plutôt une référence vers cet élément ou un pointeur adapté.
Parcourir les éléments à travers un pointeur vers un vecteur
La boucle utilise ptr->size() comme condition d’arrêt et accède à chaque valeur avec (*ptr).at(i). Ces deux opérations passent par le pointeur vers le vecteur. Vous pouvez aussi écrire l’accès indexé avec la forme fléchée, ptr->at(i) ; elle sélectionne le même membre du vecteur. std::size_t, inclus depuis <cstddef>, est un type non signé adapté à la taille du vecteur et à ses indices.
Un pointeur vers un vecteur est différent d’un itérateur du vecteur et d’un pointeur vers un élément individuel. Le pointeur de cet exemple désigne l’objet std::vector<int> dans son ensemble. Un itérateur est une position fournie par le conteneur pour parcourir ses éléments, tandis qu’un pointeur vers un élément désigne une valeur stockée. La boucle indexée distingue ces rôles et convient lorsqu’un indice est nécessaire. Si vous devez seulement visiter chaque valeur, une boucle basée sur une plage appliquée à *ptr est également possible, mais elle parcourt le vecteur sans montrer l’accès à un membre à travers le pointeur à chaque étape.
Comme l’exemple ne modifie pas le vecteur pendant le parcours, l’accès par indice reste simple. Dans un programme qui insère ou supprime des éléments pendant le parcours, réévaluez la boucle : ces opérations peuvent changer la taille du vecteur et invalider les références, pointeurs ou itérateurs vers ses éléments. Un pointeur vers l’objet vecteur continue de désigner cet objet, mais ne garantit pas la stabilité des positions des éléments. Gardez le vecteur en vie pendant chaque utilisation de son pointeur et choisissez une logique de parcours qui tient compte des modifications effectuées par votre programme.