Возврат указателя на векторный элемент в c++
у меня есть вектор myObjects в глобальном масштабе.
У меня есть метод, который использует std::vector<myObject>::const_iterator чтобы пересечь вектор и сделать некоторые сравнения, чтобы найти конкретный элемент.
Как только я нашел нужный элемент, я хочу иметь возможность вернуть указатель на него (вектор существует в глобальной области видимости).
Если я вернусь &iterator, Я возвращаю адрес итератора или адрес того, на что указывает итератор?
мне нужно бросить const_iterator вернуться к myObject, тогда верните адрес этого?
9 ответов:
возвращает адрес вещи, на которую указывает итератор:
&(*iterator)Edit: чтобы прояснить некоторую путаницу:
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 }нет необходимости в векторах указателей или динамическом выделении.
возвращение &итератор будет возвращать адрес итератора. Если вы хотите вернуть способ ссылки на элемент, верните сам итератор.
помните, что вам не нужно, чтобы вектор был глобальным, чтобы вернуть итератор/указатель, но что операции в векторе могут сделать итератор недействительным. Добавление элементов в вектор, например, может переместить векторные элементы в другое положение, если новый размер() больше, чем зарезервированная память. Удаление элемент перед заданным элементом из вектора заставит итератор ссылаться на другой элемент.
в обоих случаях, в зависимости от реализации STL, может быть трудно отлаживать только случайные ошибки, происходящие так часто.
редактировать после комментария: 'да, я не хотел возвращать итератор a) потому что его const и b) конечно, это только локальный, временный итератор? – Krakkos'
итераторы не являются более или менее локальными или временными, чем любая другая переменная и они могут быть скопированы. Вы можете вернуть его, и компилятор сделает копию для вас, как это будет с указателем.
теперь с постоянством. Если вызывающий объект хочет выполнить изменения через возвращаемый элемент (будь то указатель или итератор), то следует использовать неконстантный итератор. (Просто удалите 'const_' из определения итератора).
Это не очень хорошая идея, чтобы вернуть итераторы. Итераторы становятся недействительными, когда происходят изменения вектора (инверсия\удаление). Кроме того, итератор является локальным объектом, созданным в стеке, и поэтому возврат адреса того же самого не является безопасным. Я бы предложил вам работать с myObject, а не с векторными итераторами.
EDIT: Если объект легкий, то его лучше вернуть сам объект. Otheriwise возвращает указатели на myObject, хранящиеся в вектор.
пока ваш вектор остается в глобальной области видимости можно вернуть:
&(*iterator)Я предупреждаю вас, что это довольно опасно в целом. Если ваш вектор когда-либо перемещается из глобальной области и разрушается, любые указатели на myObject становятся недействительными. Если вы пишете эти функции как часть более крупного проекта, возврат неконстантного указателя может привести к тому, что кто-то удалит возвращаемое значение. Это будет иметь неопределенные и катастрофические последствия для приложения.
Я бы переписал это как:
myObject myFunction(const vector<myObject>& objects) { // find the object in question and return a copy return *iterator; }Если вам нужно изменить возвращенный myObject, сохраните свои значения как указатели и выделите их в куче:
myObject* myFunction(const vector<myObject*>& objects) { return *iterator; }таким образом, у вас есть контроль над тем, когда они уничтожены.
что-то вроде этого сломает ваше приложение:
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());
можно использовать данные функция вектора:
возвращает указатель на первый элемент в векторе.
если не нужен указатель на первый элемент, но по индексу, то можно попробовать, например:
//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;
скажем, у вас есть следующие:
std::vector<myObject>::const_iterator first = vObj.begin();тогда первый объект в векторе:
*first. Чтобы получить адрес, используйте:&(*first).однако, в соответствии с дизайном STL, я бы предложил вместо этого вернуть итератор, если вы планируете передать его позже алгоритмам STL.
вы храните копии myObject в векторе. Поэтому я считаю, что копирование экземпляра myObject не является дорогостоящей операцией. Тогда я думаю, что самым безопасным было бы вернуть копию myObject из вашей функции.
Я не уверен, что нужно возвращать адрес вещи, на которую указывает итератор. Все, что вам нужно, это сам указатель. Вы увидите сам класс итератора STL, реализующий использование _Ptr для этой цели. Так что, просто сделайте:
return iterator._Ptr;
Comments