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

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

Восстановить пароль Регистрация
 
fuelcs
12 / 12 / 0
Регистрация: 23.01.2013
Сообщений: 143
06.08.2013, 23:50     Удаление объекта из контейнера #1
Доброго вечера... Помогите разобраться...
Есть класс А:
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 не приведет к утечке памяти?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.08.2013, 23:50     Удаление объекта из контейнера
Посмотрите здесь:

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

Не по теме:

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


Не по теме:

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

Olivеr
 Аватар для Olivеr
411 / 407 / 13
Регистрация: 06.10.2011
Сообщений: 830
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, вероятно, будет указывать на соседний (существующий или не существующий) объект
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);
конструктор копии не обязателен? Правильно?
Olivеr
 Аватар для Olivеr
411 / 407 / 13
Регистрация: 06.10.2011
Сообщений: 830
07.08.2013, 16:33     Удаление объекта из контейнера #7
Цитата Сообщение от fuelcs Посмотреть сообщение
в результате мы работаем с объектом (через указатель) после удаления с контейнера - что это утечка памяти deque?
это не утечка. объект больше не существует. для него был вызван деструктор и его нельзя использовать. я же писал, что
Цитата Сообщение от Olivеr Посмотреть сообщение
Не факт, что дек сразу освободит память для этого объекта. Зависит от реализации.
Цитата Сообщение от fuelcs Посмотреть сообщение
конструктор копии не обязателен? Правильно?
обязателен

Добавлено через 2 минуты
добавьте еще несколько push_back'ов в ту программу (после удаления). произойдет реаллокация контейнера и разыменование ptr приведет к ошибке
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;//интересует или так правильно...
};
Olivеr
 Аватар для Olivеr
411 / 407 / 13
Регистрация: 06.10.2011
Сообщений: 830
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 копией
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);
тут мы принимаем по ссылке? как разница между определениями?
Olivеr
 Аватар для Olivеr
411 / 407 / 13
Регистрация: 06.10.2011
Сообщений: 830
07.08.2013, 17:52     Удаление объекта из контейнера #11
Цитата Сообщение от fuelcs Посмотреть сообщение
я не совсем понимаю, вы имеете ввиду так:
да, то есть инициализировать копией
Цитата Сообщение от fuelcs Посмотреть сообщение
тут мы принимаем по ссылке? как разница между определениями?
ну и с чего вы взяли, что контейнер хранит ссылки на объекты? он хранит копии!
еще раз перечитайте, что такое ссылки, почему они не могут быть неинициализированы и тд...
http://www.cplusplus.com/reference/d...que/push_back/

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

C++ C++, удаление элемента из списка "контейнера"
Удаление объекта из <vector> C++
Удаление объекта класса из контейнера C++

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

Или воспользуйтесь поиском по форуму:
Olivеr
 Аватар для Olivеr
411 / 407 / 13
Регистрация: 06.10.2011
Сообщений: 830
07.08.2013, 18:45     Удаление объекта из контейнера #15
Цитата Сообщение от fuelcs Посмотреть сообщение
Вот только как делается перемещение объектов? Не совсем понятно... Разве что внутри контейнера объекты хранятся через указатели...
это семантика перемещения в С++11. если только начинаете учить язык, то забудьте
Цитата Сообщение от fuelcs Посмотреть сообщение
Вот только, мне кажется, что логичнее будет, если там используется перегруженный оператор присваивания а не конструктор копии.
используется и то и то. для неинициализированной области памяти используется конструктор копий, а для инициализированной - оператор =.
Цитата Сообщение от fuelcs Посмотреть сообщение
Если по ссылке - тогда не вызывается.
но это не означает, что объектов становится два. ссылка - всего лишь псевдоним
Yandex
Объявления
07.08.2013, 18:45     Удаление объекта из контейнера
Ответ Создать тему
Опции темы

Текущее время: 17:09. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru