Question

J'ai un vecteur de myObjects dans une portée globale.J'ai une méthode qui utilise un std::vector<myObject>::const_iterator parcourir le vecteur et faire quelques comparaisons pour trouver un élément spécifique.Une fois que j'ai trouvé l'élément requis, je souhaite pouvoir renvoyer un pointeur vers celui-ci (le vecteur existe dans une portée globale).

Si je reviens &iterator, est-ce que je renvoie l'adresse de l'itérateur ou l'adresse de ce vers quoi l'itérateur pointe ?

Dois-je lancer le const_iterator revenir à un myObject, puis renvoyer l'adresse de celui-ci ?

Était-ce utile?

La solution

Retourne l'adresse de la chose indiquée par l'itérateur:

&(*iterator)

Modifier: Pour dissiper une certaine confusion:

vector <int> vec;          // a global vector of ints

void f() {
   vec.push_back( 1 );    // add to the global vector
   vector <int>::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 ni d’allocation dynamique.

Autres conseils

Renvoyer & amp; iterator renverra l'adresse de l'itérateur. Si vous voulez renvoyer une manière de faire référence à l'élément, retournez l'itérateur lui-même.

Attention, vous n'avez pas besoin que le vecteur soit global pour renvoyer l'itérateur / pointeur, mais que les opérations dans le vecteur peuvent invalider l'itérateur. L'ajout d'éléments au vecteur, par exemple, peut déplacer les éléments vectoriels dans 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 oblige l'itérateur à se référer à un élément différent.

Dans les deux cas, en fonction de l'implémentation de la STL, il peut être difficile de déboguer, il suffit que des erreurs aléatoires se produisent si souvent.

EDIT après commentaire: 'oui, je ne voulais pas renvoyer l'itérateur a) car il est constant, et b) ce n'est sûrement qu'un itérateur local et temporaire? & # 8211; Krakkos '

Les itérateurs ne sont ni plus ni moins locaux ou temporaires que toute autre variable et ils sont copiables. Vous pouvez le renvoyer et le compilateur en fera la copie comme il le fera avec le pointeur.

Maintenant avec la const-ness. Si l'appelant souhaite effectuer des modifications via l'élément renvoyé (qu'il s'agisse d'un pointeur ou d'un itérateur), vous devez utiliser un itérateur non const. (Supprimez simplement le 'const_' de la définition de l'itérateur).

Ce n’est pas une bonne idée de renvoyer des itérateurs. Les itérateurs deviennent invalides lorsque des modifications du vecteur (inversion \ suppression) sont effectuées. En outre, l'itérateur est un objet local créé sur une pile et, par conséquent, le renvoi de l'adresse de celui-ci n'est pas du tout sécurisé. Je vous conseillerais de travailler avec myObject plutôt qu'avec des itérateurs vectoriels.

MODIFIER: Si l'objet est léger, il est préférable de le renvoyer lui-même. Sinon, renvoyez les pointeurs vers myObject stockés dans le vecteur.

Tant que votre vecteur reste dans la portée globale, vous pouvez retourner:

&(*iterator)

Je vous préviens que c'est assez dangereux en général. Si votre vecteur quitte sa portée globale et est détruit, tous les pointeurs vers myObject ne sont plus valables. Si vous écrivez ces fonctions dans le cadre d'un projet plus vaste, le renvoi d'un pointeur non-const peut amener quelqu'un à supprimer la valeur renvoyée. Cela aura des effets non définis et catastrophiques sur l'application.

Je réécrirais ceci en tant que:

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

Si vous devez modifier l'objet myObject renvoyé, enregistrez vos valeurs sous forme de pointeurs et allouez-les sur le tas:

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

De cette façon, vous avez le contrôle sur leur destruction.

Quelque chose comme ça va casser votre application:

g_vector<tmpClass> myVector;

    tmpClass t;
    t.i = 30;
    myVector.push_back(t);

    // my function returns a pointer to a value in myVector
    std::auto_ptr<tmpClass> t2(myFunction());

Vous pouvez utiliser le données fonction du vecteur :

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

Si vous ne voulez pas le pointeur sur le premier élément, mais par index, alors 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<myObject> vec;
myObject* ptr_to_first = vec.data();

//or

std::vector<myObject>* vec;
myObject* ptr_to_first = vec->data();

//then

myObject element = ptr_to_first[i]; //element at index i
myObject* ptr_to_element = &element;

Dites, vous avez les éléments suivants:

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

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

Toutefois, conformément à la conception de la STL, je vous conseillerais de renvoyer un itérateur si vous prévoyez de le transmettre ultérieurement aux algorithmes de la 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 renvoyer une copie de myObject depuis votre fonction.

Reportez-vous aux réponses de dirkgently et anon, vous pouvez appeler la fonction avant au lieu de la fonction commencer . Ainsi, vous n'avez pas à écrire le *, mais uniquement le &.

Exemple de code:

vector<myObject> 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, i.e. 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 sais pas si le renvoi de l'adresse indiquée par l'itérateur est nécessaire. Tout ce dont vous avez besoin est le pointeur lui-même. Vous verrez que la classe itérateur de STL elle-même implémente l'utilisation de _Ptr à cette fin. Alors, faites juste:

return iterator._Ptr;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top