Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.63/8: Рейтинг темы: голосов - 8, средняя оценка - 4.63
187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335

Как удалить объект, который это попросил?

13.06.2014, 14:43. Показов 1820. Ответов 24
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Сам вопрос возник, когда работал с Qt и их системой signal/slot. Проблема на С++ выглядела бы так:
Есть два объекта: А(асинхронный) и О(ожидающий).
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
struct O
{
    A *a;
    int downloadsAmount;
    MainObject *parent;
    
    void run() // Этот метод запускается в отдельном потоке. После его окончания, поток завершается
    {
        a = new A(this);
        a->download(); // Так же создает ещё один поток для метода download();
    }
    
    void downloadFinished()
    {
        ++downloadsAmount;
        parent->data = a->data; // по некоторым причинам, Data не является указателем
        // После сохранения data в MainObject, поток А тоже завершится (на самом деле в методе download(O *parent), но не суть. Главное, что теперь копия данных в А осталась без именений - её никто не удалил. В идеале было бы сделать, как ниже :
        
        // delete a; // но так нельзя, ведь после этого метода поток вернется в методе структуры А. Да, там больше нет обращения к данным А, но всё равно - это неправильно. В моем случае, это ошибка.
    }
}
 
struct A
{
    Data d; // не указатель
    
    void download(O *parent)
    {
        /*скачиваем*/
        parent->downloadFinished();
    }
}
Как удалить объект А, созданный в другом потоке, который завершил свое исполнение? Единственное, что я придумал, это занести его в какой-то глобальный
C++
1
vector < BaseObject * > crap;
- и каждую итерацию чего-нибудь очищать этот вектор. Само собой для вектора понадобится мьютекс, иначе не thread-safe. Есть ли иное решение?
1
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
13.06.2014, 14:43
Ответы с готовыми решениями:

Есть ссылка на объект. Можно ли изменить объект, который хранится по этому адресу?
Есть ссылка на объект. Можно ли изменить объект, который хранится по этому адресу? Т.е. не меняя саму ссылку, изменить тип объекта, на...

Что значит константный указатель на объект, указатель на константный объект, и как это можно использовать?
Подскажите, что значит константный указатель на объект, указатель на константный объект, и как это можно использовать??

this это адресс объекта, а *this это сам объект. я всё правельно понял?
this это адресс объекта, а *this это сам объект. я всё правельно понял?

24
187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335
13.06.2014, 20:34  [ТС]
Студворк — интернет-сервис помощи студентам
Tulosba,

Не по теме:

почему так лучше не делать? Закинул другому классу указатель на "родителя"


Как уже писал выше, умный указатель не поможет.
Renji, как вариант, но статический класс ради такого.. Сработает, но выглядит страшно (:
Tulosba, опять-таки, разве delete this не UB?
Renji,

давайте я немного изменю условие. Есть объекты классов А и В, как в примере. ВНЕЗАПНО, появился поток, исполняющий download() класса В, который в конце этого метода перестанет существовать. Как этому потоку, исполняющему метод класса В удалить объект класса В?
Как уже писал выше, способ
C++
1
 vector < Object* > crap
не подходит по причине того, что нельзя точно узнать, завершился ли поток (signal/slot в Qt в асинхронном режиме)
0
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,531
Записей в блоге: 1
13.06.2014, 20:49
Да ладно? Где это сказано, что delete this нельзя делать? Если после dеlеtе гарантированно не происходит обращений к полям данного объекта, то вполне можно!
1
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
13.06.2014, 20:50
давайте я немного изменю условие. Есть объекты классов А и В, как в примере. ВНЕЗАПНО, появился поток, исполняющий download() класса В, который в конце этого метода перестанет существовать. Как этому потоку, исполняющему метод класса В удалить объект класса В?
Для удаления объекта класса B требуется:
1) Убедиться что на него больше никто не ссылается/не ссылался изначально/обнулить все ссылки на объект.
2) Выполнить delete.
Один у вас поток или несколько, ничего принципиально не меняется.
0
187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335
13.06.2014, 21:17  [ТС]
Kuzia domovenok, примерно с год-два назад здесь и научили меня сторожилы, что нельзя delete this, даже если не происходит ничего после.
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
13.06.2014, 21:35
Лучший ответ Сообщение было отмечено nexen как решение

Решение

this - это просто указатель на объект класса.
Если this указывает на объект, созданный в динамической памяти, к
нему вполне допустимо применять конструкцию "delete this", что
эквивалентно "delete ptr_to_object". Ни к каким побочным эффектам или
неопределенному поведению это не приведет. Такая конструкция
повсеместно используется, например, в COM. Там объект разрушает
сам себя, когда его счетчик ссылок становится равным нулю.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
13.06.2014, 21:35
Помогаю со студенческими работами здесь

Как в переменную получить объект UI на который направлена мышь?
Есть переменная типа GameObject.Нужно задать ей UI объект на который наведена мышь

Обращение к массиву в методе, который передан как объект
Передал массив в метод как объект. В методе можно извлечь свойства этого массива. Как в таком методе обратиться к элементу массива? ...

При попытке создать объект obj=Server.CreateObject('Name.ClassName') Возникает ошибка, 'Объект не поддерживает это свойство или метод.'
При попытке создать объект obj=Server.CreateObject('Name.ClassName') Возникает ошибка, 'Объект не поддерживает это свойство или метод.'...

Как реализовать метод, который превратит любой объект в byte[] ?
public static byte GetByte(object obj) { byte ret=null; //---------------------------Вот что делать с объектом? ...

Как создать объект, который будет известен только в рантайме?
var myvar:pic = new pic(); вот обычное объявление создающее экземпляр библиотеки pic а как сделать - если мне и переменная myvar и сам...


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

Или воспользуйтесь поиском по форуму:
25
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru