Retour d’un pointeur à un élément vectoriel en c ++

J’ai un vecteur de myObjects à l’échelle mondiale. J’ai une méthode qui utilise un std::vector::const_iterator pour parcourir le vecteur et faire des comparaisons pour trouver un élément spécifique. Une fois que j’ai trouvé l’élément requirejs, je veux pouvoir y retourner un pointeur (le vecteur existe dans la scope globale).

Si je retourne &iterator , est-ce que je renvoie l’adresse de l’iterator ou l’adresse de l’iterator sur lequel pointe l’iterator?

Dois-je const_iterator dans un myObject, puis renvoyer l’adresse de celui-ci?

Retourne l’adresse de la chose pointée par l’iterator:

 &(*iterator) 

Edit: Pour dissiper une certaine confusion:

 vector  vec; // a global vector of ints void f() { vec.push_back( 1 ); // add to the global vector vector ::iterator it = vec.begin(); * it = 2; // change what was 1 to 2 int * p = &(*it); // get pointer to first element * p = 3; // change what was 2 to 3 } 

Pas besoin de vecteurs de pointeurs ou d’allocation dynamic.

Retour & iterator renverra l’adresse de l’iterator. Si vous voulez renvoyer une référence à l’élément, retournez l’iterator lui-même.

Attention, vous n’avez pas besoin que le vecteur soit global pour renvoyer l’iterator / pointeur, mais les opérations dans le vecteur peuvent invalider l’iterator. L’ajout d’éléments au vecteur, par exemple, peut déplacer les éléments vectoriels vers une position différente si la nouvelle taille () est supérieure à la mémoire réservée. La suppression d’un élément avant que l’élément donné du vecteur fasse que l’iterator fasse référence à un élément différent.

Dans les deux cas, selon l’implémentation de la STL, il peut être difficile de déboguer avec des erreurs aléatoires se produisant chaque fois si souvent.

EDIT après le commentaire: ‘oui, je ne voulais pas retourner l’iterator a) parce que son const, et b) c’est sûrement seulement un iterator local et temporaire? – Krakkos ‘

Les iterators ne sont pas plus ou moins locaux ou temporaires que toute autre variable et ils sont copiables. Vous pouvez le renvoyer et le compilateur fera la copie pour vous comme avec le pointeur.

Maintenant avec la constance. Si l’appelant souhaite effectuer des modifications via l’élément renvoyé (qu’il soit un pointeur ou un iterator), vous devez utiliser un iterator non const. (Il suffit de supprimer le ‘const_’ de la définition de l’iterator).

Ce n’est pas une bonne idée de renvoyer des iterators. Les iterators deviennent invalides lorsque des modifications du vecteur (inversion \ suppression) se produisent. En outre, l’iterator est un object local créé sur la stack et le renvoi de l’adresse du même n’est donc pas du tout sécurisé. Je vous suggère de travailler avec myObject plutôt qu’avec des iterators vectoriels.

EDIT: Si l’object est léger, il est préférable de retourner l’object lui-même. Sinon, renvoyez les pointeurs vers myObject stockés dans le vecteur.

Tant que votre vecteur rest dans la scope globale, vous pouvez retourner:

 &(*iterator) 

Je vous préviens que c’est assez dangereux en général. Si votre vecteur est déplacé hors de la scope globale et est détruit, tous les pointeurs vers myObject deviennent invalides. Si vous écrivez ces fonctions dans le cadre d’un projet plus vaste, le fait de renvoyer un pointeur non-const peut conduire à supprimer la valeur renvoyée. Cela aura des effets indéfinis et catastrophiques sur l’application.

Je réécrirais ceci comme:

 myObject myFunction(const vector& objects) { // find the object in question and return a copy return *iterator; } 

Si vous devez modifier le myObject renvoyé, stockez vos valeurs en tant que pointeurs et allouez-les sur le tas:

 myObject* myFunction(const vector& objects) { return *iterator; } 

De cette façon, vous avez le contrôle quand ils sont détruits.

Quelque chose comme ça va casser votre application:

 g_vector myVector; tmpClass t; ti = 30; myVector.push_back(t); // my function returns a pointer to a value in myVector std::auto_ptr t2(myFunction()); 

Vous pouvez utiliser la fonction de données du vecteur:

Renvoie un pointeur sur le premier élément du vecteur.

Si vous ne voulez pas que le pointeur soit sur le premier élément, mais par index, vous pouvez essayer, par exemple:

 //the index to the element that you want to receive its pointer: int i = n; //(n is whatever integer you want) std::vector vec; myObject* ptr_to_first = vec.data(); //or std::vector* vec; myObject* ptr_to_first = vec->data(); //then myObject element = ptr_to_first[i]; //element at index i myObject* ptr_to_element = &element; 

Dis, tu as ce qui suit:

 std::vector::const_iterator first = vObj.begin(); 

Le premier object du vecteur est alors: *first . Pour obtenir l’adresse, utilisez: &(*first) .

Cependant, conformément à la conception de la STL, je vous suggérerais de retourner un iterator à la place si vous prévoyez de le transmettre plus tard aux algorithmes STL.

Vous stockez les copies de myObject dans le vecteur. Je pense donc que copier l’instance de myObject n’est pas une opération coûteuse. Ensuite, je pense que le plus sûr serait de retourner une copie de myObject à partir de votre fonction.

Reportez-vous aux réponses de dirkgently et anon, vous pouvez appeler la fonction front à la place de la fonction begin , vous n’avez donc pas besoin d’écrire le * , mais uniquement le & .

Exemple de code:

 vector vec; //You have a vector of your objects myObject first = vec.front(); //returns reference, not iterator, to the first object in the vector so you had only to write the data type in the generic of your vector, ie myObject, and not all the iterator stuff and the vector again and :: of course myObject* pointer_to_first_object = &first; //* between & and first is not there anymore, first is already the first object, not iterator to it. 

Je ne suis pas sûr que le renvoi de l’adresse de l’object indiqué par l’iterator soit nécessaire. Tout ce dont vous avez besoin est le pointeur lui-même. Vous verrez la classe d’iterator de STL implémenter l’utilisation de _Ptr à cette fin. Alors, faites simplement:

 return iterator._Ptr;