punteros puntero declaracion cadenas aritmetica apuntadores c++ pointers containers iterator

declaracion - punteros c++ pdf



Devolver un puntero a un elemento vectorial en c++ (9)

Tengo un vector de myObjects en el alcance global. Tengo un método que usa std::vector<myObject>::const_iterator para recorrer el vector y hacer algunas comparaciones para encontrar un elemento específico. Una vez que he encontrado el elemento requerido, quiero poder devolver un puntero (el vector existe en el alcance global).

Si devuelvo &iterator , ¿estoy devolviendo la dirección del iterador o la dirección a la que apunta el iterador?

¿Debo const_iterator el const_iterator a const_iterator y luego devolver la dirección?


Consulte las respuestas de dirkgently y anon, puede llamar a la función frontal en lugar de a la función de inicio , para que no tenga que escribir el * , sino solo el & .

Ejemplo de código:

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.


Devuelve la dirección de la cosa señalada por el iterador:

&(*iterator)

Editar: para aclarar algo de confusión:

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 }

No hay necesidad de vectores de punteros o asignación dinámica.


Diga, usted tiene lo siguiente:

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

Entonces el primer objeto en el vector es: *first . Para obtener la dirección, use: &(*first) .

Sin embargo, de acuerdo con el diseño de STL, sugeriría devolver un iterador en su lugar si planea pasarlo más tarde a los algoritmos de STL.


Está almacenando las copias del myObject en el vector. Así que creo que copiar la instancia de myObject no es una operación costosa. Entonces creo que lo más seguro sería devolver una copia del myObject de tu función.


Mientras su vector permanezca en alcance global, puede devolver:

&(*iterator)

Te advierto que esto es bastante peligroso en general. Si su vector alguna vez se mueve fuera del alcance global y se destruye, cualquier puntero a myObject se vuelve inválido. Si está escribiendo estas funciones como parte de un proyecto más grande, devolver un puntero que no sea const podría llevar a que alguien borre el valor de retorno. Esto tendrá efectos indefinidos y catastróficos en la aplicación.

Yo volvería a escribir esto como:

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

Si necesita modificar el myObject devuelto, almacene sus valores como punteros y distribúyalos en el montón:

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

De esa forma tienes control sobre cuándo se destruyen.

Algo como esto romperá tu aplicación:

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());


No es una buena idea devolver iteradores. Los iteradores se vuelven inválidos cuando ocurren modificaciones en el vector (inversión / eliminación). Además, el iterador es un objeto local creado en la pila y, por lo tanto, devolver la dirección del mismo no es para nada seguro. Te sugiero que trabajes con myObject en lugar de iteradores de vectores.

EDITAR: Si el objeto es liviano, es mejor que devuelva el objeto en sí. Punteros de regreso a myObject almacenados en el vector.


No estoy seguro de si es necesario devolver la dirección de la cosa señalada por el iterador. Todo lo que necesitas es el puntero en sí. Verá que la clase de iterador de STL está implementando el uso de _Ptr para este propósito. Entonces, solo hazlo:

return iterator._Ptr;


Puedes usar la función de datos del vector:

Devuelve un puntero al primer elemento en el vector.

Si no desea el puntero al primer elemento, sino por índice, puede intentar, por ejemplo:

//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;


Returning & iterator devolverá la dirección del iterador. Si desea devolver una forma de referirse al elemento, devuelva el iterador mismo.

Tenga en cuenta que no necesita que el vector sea global para devolver el iterador / puntero, pero que las operaciones en el vector pueden invalidar el iterador. Agregar elementos al vector, por ejemplo, puede mover los elementos del vector a una posición diferente si el nuevo tamaño () es mayor que la memoria reservada. La eliminación de un elemento antes del elemento dado del vector hará que el iterador se refiera a un elemento diferente.

En ambos casos, dependiendo de la implementación de STL, puede ser difícil depurar con errores aleatorios que ocurren cada tanto.

EDITAR después del comentario: ''sí, no quería devolver el iterador a) porque es const, yb) seguramente solo es un iterador local temporal? - Krakkos

Los iteradores no son más o menos locales o temporales que cualquier otra variable y se pueden copiar. Puede devolverlo y el compilador hará la copia para usted como lo hará con el puntero.

Ahora con la const-ness. Si la persona que llama desea realizar modificaciones a través del elemento devuelto (ya sea puntero o repetidor), entonces debe usar un iterador no const. (Simplemente elimine el ''const_'' de la definición del iterador).