| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > [QT] Почему нельзя удалить объект в слоте? |
| Автор: null56 18.12.2008, 11:36 |
| Ну собственно вопрос стоит так: 1) связываю сигнал от объекта с обработчиком 2) в случае неудачи вызывается соответствующий слот 3) хочу удалить вызывающий объект из этого слота... Ругается и если delete ((SslSocket *)sender()) и если удаляю сохранненый указатель на этот объект Как можно удалить объект из слота, который он вызвал? Добавлю лишь: 1) что этот слот связан с несколькими сигналами 2) объект создается динамически Заранее благодарен Добавлено через 6 минут и 4 секунды хотя sender()->deleteLater() помог... Это корректно? он динамический объект точно удалил, я это проверил в деструкторе этого объекта? |
| Автор: SABROG 18.12.2008, 11:59 |
| Да deleteLater() хороший вариант, т.к. объект удалится после возвращения в eventloop. И его можно вызывать многократно безопасно, например, если на один слот приходит несколько сигналов. Тролли честно предупреждают, что при использовании sender() надо быть осторожным с удалением объекта если к одному слоту подключено несколько сигналов, а также о том, что указатель, который возвращает sender не одно и то же, что и this. Т.е. при каждом попадании в слот указатель возвращаемый sender'ом может быть разным и валидным только пока слот выполняется, пока объект существует и пока сигнал законнекчен к слоту. Но это, если я правильно все понял. |
| Автор: null56 18.12.2008, 12:22 | ||||||||
Просто вот чего я пытаюсь сделать....
Далее функции обработки ready()
И функция изменения состояния:
После создания нового подключения, я соединяю сигналами с нужными слотами в таймауте рву соединение со стороны клиента и запускаю startServerEnclytion... Получается, что объект не удалится, пока не отработают все его сигналы, потому что вывод в консоль показывает, дважды вызов на событие stateChange() Вывод в консоль
|
| Автор: SABROG 18.12.2008, 12:41 | ||
| Первый раз приходит QAbstractSocket::ClosingState, типа дожидаемся завершения получения данных, если такие есть и закрываемся. Второй раз приходит QAbstractSocket::UnconnectedState, типа закрылись. Думается мне что все-таки придется делать два слота и прописать в них соотв. параметры, чтобы отслеживать состояние сокета и удалять объект только при приходе QAbstractSocket::UnconnectedState. Кстати интересно, при таком подходе будет утечка памяти или нет.
Ведь если сигнал пихает каждый раз параметр в стек, а этот стек слот не очищает при retn считая, что у него нет параметров. |
| Автор: null56 18.12.2008, 12:43 | ||||
| Сейчас создал метод getMe() {return this;} Через него сделал в обработчике disconnect(getMe, 0, this, 0); После дисконекта ругнулся на QCoreApplication::postEvent: Unexpected null receiver, что в принципе логично наверное...
А в одном слоте состояние сокета нельзя проверить разьве? Добавлено @ 12:48 Слот, я так понял неделимая операция, пока не отработает, другой сигнал его прервать не может... это видно из моего примера Добавлено @ 12:52
Здесь в стек кладется объект QList<QSslError &> - это объект, который занимает память, утечки никак не будет Просто доступа к этой переменной нет внутри функции, а получить через указатель стека, наверняка можно |
| Автор: null56 18.12.2008, 13:06 |
| Хотя хз... смотря кто стек чистит... вызывающая или вызываемая. Вот если вызываемая, то он когда не знает ничего об этой переменной, но думаю в qt все продумано, так как если бы он не удалял из стека область памяти, которую занимает эта перменная, то он бы не добрался до адреса возврата, который находится ниже в стеке, так что думаю, чистится все граммотно + у меня в книжке от создателей написано, что если у сигнала больше параметров, чем у слота, то остальные параметры будут игнорироваться ) |
| Автор: SABROG 18.12.2008, 13:51 |
| Да, что-то я подзабыл ассемблер |
| Автор: null56 18.12.2008, 13:58 |
| Конечно по хорошему надо посмотреть это дело в дебагаре, если не верить книжке, но в самом правильном случае лучше конечно разделить на два разных слота, так и гибче будет |