Подтвердить что ты не робот

Возвращение указателя на векторный элемент в С++

У меня есть вектор myObjects в глобальной области. У меня есть метод, который использует std::vector<myObject>::const_iterator для перемещения вектора и выполнения некоторых сравнений для поиска определенного элемента. Как только я найду необходимый элемент, я хочу, чтобы он мог вернуть ему указатель (вектор существует в глобальной области).

Если я вернусь &iterator, возвращаю ли я адрес итератора или адрес, на который указывает итератор?

Мне нужно вернуть const_iterator обратно в объект myObject, а затем вернуть адрес этого файла

4b9b3361

Ответ 1

Возвращает адрес объекта, на который указывает итератор:

&(*iterator)

Изменить: Чтобы устранить некоторую путаницу:

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
}

Нет необходимости в векторах указателей или динамическом распределении.

Ответ 2

Возвращаемый итератор вернет адрес итератора. Если вы хотите вернуть способ обращения к элементу, возвращайте сам итератор.

Остерегайтесь, чтобы вектор не был глобальным, чтобы возвращать итератор/указатель, но эти операции в векторе могут аннулировать итератор. Например, добавление элементов в вектор может перемещать векторные элементы в другую позицию, если новый размер() больше зарезервированной памяти. Удаление элемента перед данным элементом из вектора заставит итератор ссылаться на другой элемент.

В обоих случаях, в зависимости от реализации STL, его трудно отлаживать с помощью случайных ошибок, которые случаются так часто.

ИЗМЕНИТЬ после комментария: "да, я не хотел возвращать итератор а), потому что его const, и b) наверняка это только локальный, временный итератор? - Krakkos '

Итераторы не более или менее локальны или временны, чем любая другая переменная, и они могут быть скопированы. Вы можете вернуть его, и компилятор сделает копию для вас, как это будет с указателем.

Теперь с константой. Если вызывающий объект хочет выполнить изменения через возвращаемый элемент (будь то указатель или итератор), вы должны использовать неконстантный итератор. (Просто удалите 'const_' из определения итератора).

Ответ 3

Не рекомендуется возвращать итераторы. Итераторы становятся недействительными, когда происходят изменения в векторе (инверсия\удаление). Кроме того, итератор - это локальный объект, созданный в стеке и, следовательно, возвращающий его адрес совсем не безопасен. Я предлагаю вам работать с myObject, а не с векторными итераторами.

EDIT: Если объект является легким, тогда его лучше вернуть объект. OtherIwise возвращает указатели на myObject, хранящиеся в векторе.

Ответ 4

Пока ваш вектор остается в глобальной области действия, вы можете вернуться:

&(*iterator)

Я предупреждаю вас, что это вообще довольно опасно. Если ваш вектор когда-либо выведен из глобальной области и разрушен, любые указатели на myObject становятся недействительными. Если вы пишете эти функции как часть более крупного проекта, возврат указателя не const может привести к тому, что кто-то удалит возвращаемое значение. Это будет иметь undefined и катастрофические последствия для приложения.

Я бы переписал это как:

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

Ответ 5

Вы можете использовать функцию данных для вектора:

Возвращает указатель на первый элемент в векторе.

Если вы не хотите, чтобы указатель на первый элемент, но по индексу, вы можете попробовать, например:

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

Ответ 6

Скажем, у вас есть следующее:

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

Тогда первый объект в векторе: *first. Чтобы получить адрес, используйте: &(*first).

Однако, в соответствии с дизайном STL, я бы предложил вместо этого возвратить итератор, если вы планируете передать его позже на алгоритмы STL.

Ответ 7

Вы сохраняете копии объекта myObject в векторе. Поэтому я считаю, что копирование экземпляра myObject не является дорогостоящей операцией. Тогда я думаю, что самый безопасный будет возвращать копию myObject из вашей функции.

Ответ 8

Обратитесь к dirkgently и anon ответам, вы можете вызвать функцию front вместо функции begin, поэтому вы не должны писать *, но только &.

Пример кода:

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.

Ответ 9

Я не уверен, что нужно вернуть адрес вещи, указанной итератором. Все, что вам нужно, это сам указатель. Вы увидите, что класс итератора STL сам использует использование _Ptr для этой цели. Итак, просто выполните:

return iterator._Ptr;