Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Devilox
3 / 3 / 2
Регистрация: 19.02.2014
Сообщений: 109
#1

Удаления элемента Vector-а по имени - C++

21.02.2014, 21:45. Просмотров 440. Ответов 11
Метки нет (Все метки)

У меня есть вот такая функция создания экземпляра класса в динамической памяти:
C++
1
2
3
4
5
6
7
8
9
dxDot* dxCreateDot(float x, float y, char symbol) {
    dxDot* Temp = new dxDot(x, y, symbol);
    DotsArray.push_back(*Temp);
 
    return Temp;
 
    delete Temp;
    Temp = 0;
}
Мне нужно написать что-то подобное для удаления экземпляра класса dxDot. Очистка места в памяти понятна, а вот в массиве типа vector - нет. Читал про итераторы, но их ведь тоже нужно инициализировать, а как удалять - непонятно (пробовал через указатель - не получается). Что в таком случае необходимо делать?
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.02.2014, 21:45
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Удаления элемента Vector-а по имени (C++):

Передачи функции имени вектора со структурой (vector+struct >> some function) - C++
Доброе время суток!! Помогите разобраться с передачей функции в качестве аргумента весь вектор со структурой Собственно пишу из...

Формирования массивов Y и Z, определения максимального по модулю элемента, удаления элемента - C++
Из массива Х(N) все положительные элементы записать в массив Y(k), а все отрицательные элементы – в массив Z(m). Найти в каждом массиве...

Удаление элемента из vector - C++
Подскажите как удалить 1 элемент из массива типа vector, delete не работает почему-то?

Передача vector с i-го элемента - C++
можно ли вектор передавать с i-го элемента, кто знает, подскажите void ARR(int arr) { cout << arr << endl; // arr = 6 } void...

Удаление элемента из vector - C++
Здорова! Пытаюсь удалить элемент из vector<string>, но чото ошибку выдает и я вообще не пойму что за ошибка. Вот код который ошибку...

Реализовать приложение, содержащее функции добавления нового элемента в массив и удаления элемента из массива. (Имитируется “резиновый” массив) - C++
Реализовать приложение, содержащее функции добавления нового элемента в массив и удаления элемента из массива. (Имитируется “резиновый”...

11
DrOffset
7351 / 4451 / 1009
Регистрация: 30.01.2014
Сообщений: 7,292
21.02.2014, 21:52 #2
Цитата Сообщение от Devilox Посмотреть сообщение
У меня есть вот такая функция создания экземпляра класса в динамической памяти
Начать с того, что эта функция с утечкой и вообще делает совсем не то, что вы думаете.
Вот правильный вариант:
C++
1
2
3
4
dxDot* dxCreateDot(float x, float y, char symbol) {
    DotsArray.push_back(dxDot(x, y, symbol));
    return &DotsArray.back();
}
Ну и уточняющий вопрос. По какому критерию нужно удалять? (от этого зависит ответ)
1
Devilox
3 / 3 / 2
Регистрация: 19.02.2014
Сообщений: 109
21.02.2014, 21:59  [ТС] #3
DrOffset, мне нужно осуществить то же удаление, что и при вызове .erase(i), но по указателю(если, конечно, это возможно).
0
Megabar
22 / 22 / 3
Регистрация: 01.12.2013
Сообщений: 93
21.02.2014, 22:08 #4
Devilox, если объект расположен в автоматическом классе памяти, сделать .erase(i) будет достаточно.
если объект динамический, делаете delete DotsArray[i], а потом .erase(i)
0
Devilox
3 / 3 / 2
Регистрация: 19.02.2014
Сообщений: 109
21.02.2014, 22:17  [ТС] #5
Megabar, проблема лишь в том, что нужно инициализировать итератор, чего делать мне не очень-то хочется. Можно ли обойтись ссылками или указателями? (Или же я преувеличиваю с итераторами, и они проще, чем мне кажутся?)
0
DrOffset
7351 / 4451 / 1009
Регистрация: 30.01.2014
Сообщений: 7,292
21.02.2014, 22:29 #6
Цитата Сообщение от Devilox Посмотреть сообщение
DrOffset, мне нужно осуществить то же удаление, что и при вызове .erase(i), но по указателю(если, конечно, это возможно).
В случае вектора можно получить индекс элемента просто посчитав разницу указателей:
C++
1
size_t index = std::distance(&vec[0], ptr);
где ptr - искомый для удаления указатель.

Но здесь скрыта еще одна проблема. Т.к. вектор хранит свои элементы в непрерывной памяти, при добавлении новых элементов сохраненные указатели на элементы могут стать невалидными. В случае итератора на элемент вектора - произойдет тоже самое.
Тут есть несколько вариантов.
Можно сменить тип контейнера на тот, который не инвалидирует итераторы при добавлении. Например std::list (соответственно использовать итераторы list).
Либо можно сменить тип указателя на элемент на что-нибудь независимое, например на индекс.
Можно в векторе вообще не хранить объекты, а хранить только указатели на них. Но тогда для поиска значения по указателю придется делать цикл по всем элементам. А в конце еще пробежаться по содержимому и вызвать всем delete.
Каждый из вариантов потребует переписывания функций удаления\добавления.
1
Kuzia domovenok
1892 / 1747 / 119
Регистрация: 25.03.2012
Сообщений: 5,936
Записей в блоге: 1
21.02.2014, 22:36 #7
Инициализируй итератор с помощью remove. Потом освобождай память и удаляй через erase!
1
Devilox
3 / 3 / 2
Регистрация: 19.02.2014
Сообщений: 109
21.02.2014, 22:36  [ТС] #8
Спасибо)
0
Kuzia domovenok
1892 / 1747 / 119
Регистрация: 25.03.2012
Сообщений: 5,936
Записей в блоге: 1
21.02.2014, 22:40 #9
DrOffset, вообще-то у него не указатель на элемент вектора, а вектор указателей.(указатели произвольные на объекты в куче)
0
DrOffset
7351 / 4451 / 1009
Регистрация: 30.01.2014
Сообщений: 7,292
21.02.2014, 22:42 #10
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Про индексы я зря сказал, потому что если вы будете удалять из середины - придется их пересчитывать.
Плюс вектор не очень хорош на задачах (опять же потому, что требует непрерывности), где нужно удалять из середины коллекции.
В общем, как мне кажется, лучший вариант (с учетом удаления из середины) вот такой:
C++
1
2
3
4
5
6
7
8
9
10
11
// 1
// или std::deque 
// используем везде итераторы вместо указателей
std::list<dxDot>::iterator dxCreateDot(float x, float y, char symbol) {
    return DotsList.insert(DotsList.end(), dxDot(x, y, symbol));
}
 
void dxRemoveDot(std::list<dxDot>::iterator remIter)
{
    DotsList.erase(remIter);
}
Добавлено через 1 минуту
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
вообще-то у него не указатель на элемент вектора, а вектор указателей.(указатели произвольные на объекты в куче)
Вообще-то в его первом посте явно видно, что указатель он разыменовывает. Так что это спорное утверждение.
1
Devilox
3 / 3 / 2
Регистрация: 19.02.2014
Сообщений: 109
21.02.2014, 22:49  [ТС] #11
Спасибо за помощь! Тут новой информации мне ещё на неделю. Буду разбираться.
0
DrOffset
7351 / 4451 / 1009
Регистрация: 30.01.2014
Сообщений: 7,292
21.02.2014, 22:58 #12
Цитата Сообщение от Devilox Посмотреть сообщение
Или же я преувеличиваю с итераторами, и они проще, чем мне кажутся?
В случае, когда указатели принадлежат некой последовательности - они являются частным случаем итератора. Помните об этом, когда будете с ними работать. У итераторов STL сохранена семантика указателя, т.е:
Его можно разыменовать, чтобы получить значение.
Для него определена операция -> для обращения к данным или методам объекта.
1
21.02.2014, 22:58
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.02.2014, 22:58
Привет! Вот еще темы с ответами:

Удаление элемента из std::vector<> - C++
- Здравствуйте завсегдатаи! Подскажите пожалуйста, можно ли из STL-ского вектора std::vector&lt;int&gt; удалить не последний элемент (с...

vector. Заменить 3 элемента в середине одним - C++
Допустим есть вектор с 10 эл-ми, нужно элементы под номерами 3,4,5 заменить одним. Как это можно сделать? Заранее благодарен.

Обращение к полю элемента std::vector'a - C++
Здравстуйте! :) Несильно знаком с STL пока, возникла проблемка. Есть класс: class DataBase { public: char Surname; int...

Вставка (с указанием положения) и удаление элемента в vector - C++
Помогите сделать вставку с указанием положения #include &lt;iostream&gt; #include &lt;vector&gt; #include &lt;list&gt; using namespace std; int...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru