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

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

Войти
Регистрация
Восстановить пароль
 
fuelcs
12 / 12 / 0
Регистрация: 23.01.2013
Сообщений: 143
#1

Удаление объекта из контейнера - C++

06.08.2013, 23:50. Просмотров 834. Ответов 14
Метки нет (Все метки)

Доброго вечера... Помогите разобраться...
Есть класс А:
C++
1
2
3
class A
{
};
В нем метод В:
C++
1
2
3
...
void B (std::deque<А> &С , unsigned index);
...
И есть контейнер С, который содержит объекты класса А:
C++
1
std::deque<А> С;
Вопрос: могу ли я внутри метода В удалить объект класса с контейнера С:
C++
1
2
3
4
5
6
7
8
9
void A::B (std::deque<А> &С , unsigned index)
{
...
if (<условие>)
{
     C.erase(C.begin()+index);
}
...
}
И небольшое дополнение: удаление объекта с контейнера std::deque не приведет к утечке памяти?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.08.2013, 23:50
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Удаление объекта из контейнера (C++):

Удаление объекта класса из контейнера - C++
Подскажите пожалуйста как правильно удалить обьект. MyCarDeque.push_front(*CreateNewCar()); Так добавлял обьект в очередь. Car...

Как вызвать метод объекта из контейнера? - C++
Есть абстрактный класс E, производный от CObject, в нем чистая виртуальная войдовская функция. Создал динамические объекты классов, которые...

Удаление элемента из контейнера и итераторы - C++
Кто знает при удалении элемента из контейнера через итератор, этот итератор становится недействительным и продолжать его использовать это...

C++, удаление элемента из списка "контейнера" - C++
Всем привет, знаю что вы разбираетесь больше в программировании, я новичок еще новичок, объясните пожалуйста построчно как выполняются...

удаление объекта - C++
Суть проблемы: Все происходит в одном классе. Создаю в одной функции объект. Например в .h файле пишу Bitmap* bitmap. А в .cpp bitmap = new...

Удаление объекта - C++
Добрый вечер! Я бы хотел уточнить. Если у нас есть такая структура, class A{ private: public: A(); ~A(); };

14
Olivеr
412 / 408 / 13
Регистрация: 06.10.2011
Сообщений: 832
07.08.2013, 00:00 #2
да, можете
нет, это уже проблемы std::deque
1
RealMogAika
2 / 2 / 0
Регистрация: 02.05.2013
Сообщений: 8
07.08.2013, 00:09 #3
Есть одно но. После удаления объекта, не рекомендуется использовать его переменные. Ведь указатель this будет указывать на неверное значение
1
fuelcs
12 / 12 / 0
Регистрация: 23.01.2013
Сообщений: 143
07.08.2013, 11:32  [ТС] #4
Цитата Сообщение от Olivеr Посмотреть сообщение
да, можете
Буду благодарен если кто-то просветит в механизме работы класса (методов класса)
Метод запускается как обычная функция? То есть есть точка возврата в функцию, которая его вызвала, без привязки к самому объекту?
Ведь указатель this будет указывать на неверное значение
Мне почему-то кажется, что указатель this до завершения работы метода должен сохранятся, просто он будет указывать на область памяти которая уже очищена...

Не по теме:

И с точки зрения архитектуры, подход когда объект удаляет сам себя правильный? Пишу, впервые на классах, простенькую игру. С построением объектов проблем не возникло, а вот и их взаимодействием просто беда. Уже сто раз переписывал...


Не по теме:

Для обсуждение архитектуры, в частности обработчика коллизий, создать новый топик?

0
Olivеr
412 / 408 / 13
Регистрация: 06.10.2011
Сообщений: 832
07.08.2013, 15:05 #5
C++
1
delete this;
в методе класса вполне законно, но дальнейшее использование этого объекта является очень грубой ошибкой.
Цитата Сообщение от fuelcs Посмотреть сообщение
Буду благодарен если кто-то просветит в механизме работы класса (методов класса)
deque::erase вызывает деструктор для объекта на который указывает внутренний указатель. Короче говоря, он уничтожает объект. Не факт, что дек сразу освободит память для этого объекта. Зависит от реализации.
Цитата Сообщение от fuelcs Посмотреть сообщение
Метод запускается как обычная функция? То есть есть точка возврата в функцию, которая его вызвала, без привязки к самому объекту?
В каком смысле? Она работает как обычная функция и никакого отношения к классу объектов, которые хранит, не имеет.
C++
1
2
3
4
5
6
7
8
9
10
void A::B (std::deque<А> &С , unsigned index)
{
...
if (<условие>)
{
     C.erase(C.begin()+index);
//продолжит выполнение здесь
}
...
}
Цитата Сообщение от fuelcs Посмотреть сообщение
Мне почему-то кажется, что указатель this до завершения работы метода должен сохранятся, просто он будет указывать на область памяти которая уже очищена...
он будет указывать бог знает на что. после delete this(деструктор + освобождение памяти) его нельзя использовать, после deque::erase(деструктор + (не факт) освобождение памяти) использовать нельзя. если во втором случае не будет освобождение памяти, то this, вероятно, будет указывать на соседний (существующий или не существующий) объект
0
fuelcs
12 / 12 / 0
Регистрация: 23.01.2013
Сообщений: 143
07.08.2013, 16:27  [ТС] #6
Цитата Сообщение от Olivеr Посмотреть сообщение
он будет указывать бог знает на что
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <deque>
 
class Class
{
public:
    Class()
    {
        a=10;
    }
    Class* B (std::deque<Class> &deq , unsigned index)
    {
        if (!deq.empty())
        {
            std::cout << this << "\n";//выдаст одну и ту же ячейку
            deq.erase(deq.begin()+index);
            std::cout << this << "\n";//выдаст одну и ту же ячейку
            B(deq,0);
        }
        else
        {
            std::cout << "end" << "\n";
            std::cout << a << "\n";//напечатает 10
        }
        return this;
    }
private:
    int a;
};
 
void foo (std::deque<Class> &deq)
{
    Class temp;
    deq.push_back(temp);
}
 
int main()
{
    std::deque<Class> deq;
    Class *ptr;
 
    foo(deq);
    ptr=deq[0].B(deq,0);
    
    ptr->B(deq,0);//тоже сработает - напечатает end 10;
    return 0;
}
в результате мы работаем с объектом (через указатель) после удаления с контейнера - что это утечка памяти deque?

И еще одно, для
C++
1
deq.push_back(temp);
конструктор копии не обязателен? Правильно?
0
Olivеr
412 / 408 / 13
Регистрация: 06.10.2011
Сообщений: 832
07.08.2013, 16:33 #7
Цитата Сообщение от fuelcs Посмотреть сообщение
в результате мы работаем с объектом (через указатель) после удаления с контейнера - что это утечка памяти deque?
это не утечка. объект больше не существует. для него был вызван деструктор и его нельзя использовать. я же писал, что
Цитата Сообщение от Olivеr Посмотреть сообщение
Не факт, что дек сразу освободит память для этого объекта. Зависит от реализации.
Цитата Сообщение от fuelcs Посмотреть сообщение
конструктор копии не обязателен? Правильно?
обязателен

Добавлено через 2 минуты
добавьте еще несколько push_back'ов в ту программу (после удаления). произойдет реаллокация контейнера и разыменование ptr приведет к ошибке
0
fuelcs
12 / 12 / 0
Регистрация: 23.01.2013
Сообщений: 143
07.08.2013, 16:55  [ТС] #8
Цитата Сообщение от Olivеr Посмотреть сообщение
обязателен
просто я подумал что
C++
1
deque.push_back
принимает новые элементы по ссылке и не надо заморачиватся с конструктором копий...
void push_back (const value_type& val);
void push_back (value_type&& val);
Тогда подскажите для моего класса:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class worm
{
public:
    worm(void);
    worm(std::deque<coords> source_coords);
    ~worm(void);
    void Draw(void);
    bool Move(void);
    void SetDirection(void);
    std::deque<coords> CutWorm (coords cut_point);
private:
    std::deque<coords> snake_coords;
    ConsoleColor color;
    coords direction;
    int turn_counter;
    int life_counter;
    void Turn(void);
};
как писать конструктор копий?
Этого достаточно:
C++
1
2
3
4
worm& worm (const worm& source) : color(source.color), direction(source.direction), turn_counter(source.turn_counter), life_counter (source.life_counter)
{
    snake_coords = source.snake_coords;//интересует или так правильно...
};
0
Olivеr
412 / 408 / 13
Регистрация: 06.10.2011
Сообщений: 832
07.08.2013, 17:03 #9
Цитата Сообщение от fuelcs Посмотреть сообщение
принимает новые элементы по ссылке и не надо заморачиватся с конструктором копий...
принимает по ссылке на константу и делает копию, вторая сигнатура - перемещает объект
Цитата Сообщение от fuelcs Посмотреть сообщение
worm& worm (const worm& source) : color(source.color), direction(source.direction), turn_counter(source.turn_counter), life_counter (source.life_counter)
{
* * snake_coords = source.snake_coords;//интересует или так правильно...
};
нет
это что делает в конструкторе?
Цитата Сообщение от fuelcs Посмотреть сообщение
worm&
C++
1
2
3
4
5
6
worm (const worm &source)
    : snake_coords(source.snake_coords),
      color(source.color),
      direction(source.direction),
      turn_counter(source.turn_counter),
      life_counter(source.life_counter) {}
в принципе можете вообще его не писать. компилятор синтезирует аналогичный конструктор. (он у вас очень тривиальный)

Добавлено через 1 минуту
Цитата Сообщение от fuelcs Посмотреть сообщение
snake_coords = source.snake_coords;//интересует или так правильно...
так тоже правильно, но до этого моменту std::deque<coords> snake_coords; был создан используя конструктор по умолчанию
так накладнее, лучше сразу инициализировать snake_coords копией
0
fuelcs
12 / 12 / 0
Регистрация: 23.01.2013
Сообщений: 143
07.08.2013, 17:32  [ТС] #10
Цитата Сообщение от Olivеr Посмотреть сообщение
так тоже правильно, но до этого моменту std::deque<coords> snake_coords; был создан используя конструктор по умолчанию так накладнее, лучше сразу инициализировать snake_coords копией
я не совсем понимаю, вы имеете ввиду так:
Цитата Сообщение от Olivеr Посмотреть сообщение
Код C++
worm (const worm &source)
: snake_coords(source.snake_coords),
color(source.color),
direction(source.direction),
turn_counter(source.turn_counter),
life_counter(source.life_counter) {}
Цитата Сообщение от Olivеr Посмотреть сообщение
принимает по ссылке на константу и делает копию, вторая сигнатура - перемещает объект
в данном случае:
C++
1
2
Class temp;
    deq.push_back(temp);
тут мы принимаем по ссылке? как разница между определениями?
0
Olivеr
412 / 408 / 13
Регистрация: 06.10.2011
Сообщений: 832
07.08.2013, 17:52 #11
Цитата Сообщение от fuelcs Посмотреть сообщение
я не совсем понимаю, вы имеете ввиду так:
да, то есть инициализировать копией
Цитата Сообщение от fuelcs Посмотреть сообщение
тут мы принимаем по ссылке? как разница между определениями?
ну и с чего вы взяли, что контейнер хранит ссылки на объекты? он хранит копии!
еще раз перечитайте, что такое ссылки, почему они не могут быть неинициализированы и тд...
http://www.cplusplus.com/reference/deque/deque/push_back/

Добавлено через 50 секунд
Цитата Сообщение от fuelcs Посмотреть сообщение
разница между определениями
читайте, что такое rvalue reference
1
fuelcs
12 / 12 / 0
Регистрация: 23.01.2013
Сообщений: 143
07.08.2013, 18:03  [ТС] #12
Цитата Сообщение от Olivеr Посмотреть сообщение
ну и с чего вы взяли, что контейнер хранит ссылки на объекты? он хранит копии!
вы меня не правильно поняли... я имел ввиду что в функцию push_back аргументы передаются по ссылке, не по значению и отсюда для объекта не нужно вызывать (не вызывается) конструктор копии.... возможно я ошибаюсь...
0
Olivеr
412 / 408 / 13
Регистрация: 06.10.2011
Сообщений: 832
07.08.2013, 18:05 #13
ошибаетесь. константная ссылка - всего лишь средство коммуникации, можно так сказать. исходя из того, на что она указывает делается копия
1
fuelcs
12 / 12 / 0
Регистрация: 23.01.2013
Сообщений: 143
07.08.2013, 18:42  [ТС] #14
Olivеr, мне кажется я понял
Возможно...
Нас учили что когда в функцию передаются (или возвращается) объект по значению тогда вызывается конструктор копии. Если по ссылке - тогда не вызывается.
В контейнере лежат копии наших объектов.
Вот только, мне кажется, что логичнее будет, если там используется перегруженный оператор присваивания а не конструктор копии.
Вот только как делается перемещение объектов? Не совсем понятно... Разве что внутри контейнера объекты хранятся через указатели...
0
Olivеr
412 / 408 / 13
Регистрация: 06.10.2011
Сообщений: 832
07.08.2013, 18:45 #15
Цитата Сообщение от fuelcs Посмотреть сообщение
Вот только как делается перемещение объектов? Не совсем понятно... Разве что внутри контейнера объекты хранятся через указатели...
это семантика перемещения в С++11. если только начинаете учить язык, то забудьте
Цитата Сообщение от fuelcs Посмотреть сообщение
Вот только, мне кажется, что логичнее будет, если там используется перегруженный оператор присваивания а не конструктор копии.
используется и то и то. для неинициализированной области памяти используется конструктор копий, а для инициализированной - оператор =.
Цитата Сообщение от fuelcs Посмотреть сообщение
Если по ссылке - тогда не вызывается.
но это не означает, что объектов становится два. ссылка - всего лишь псевдоним
0
07.08.2013, 18:45
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.08.2013, 18:45
Привет! Вот еще темы с ответами:

Удаление объекта класса - C++
Помогите с удалением объекта класса: void badstuddel(Student spis, int n) { for(int i=0;i&lt;n;i++) ...

Удаление объекта из <vector> - C++
Подскажите, пожалкуйста Имею следующий код: EditTest() - friend фукнция для другого класса, в нее мы входим и перемещаемся уже...

Удаление объекта из вектора - C++
Как удалить объект из вектора в таком случае: Main *mn = new Main(wd,100,100); objArray.push_back(*mn);

удаление объекта класса SFML - C++
проблема вот в чем. когда я удаляю объект класса программно то у меня вылетает окно SFML. #include &lt;SFML/Graphics.hpp&gt; #include &quot;map.h&quot;...


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

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

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