Наследование от wxEvtHandler , уничтож Topic is solved
Наследование от wxEvtHandler , уничтож
Здравствуйте. Имеется необходимость создать класс, умеющий принимать сообщения( аля от wxPostEvent ). Самым логичным показалось унаследовать класс от wxEvtHandler. Таким образом последнее время и поступал, пока не начлася падёж на одном из таких классов. После продолжительных поисков причину нашел(кажется). Заключается она в том что при удалении объекта такого класса в очереди сообщений еще могут остаться к нему необработанные сообщения. Тоже самое, насколько я знаю, случается если удалять через delete объекты, унаследованные от wxWindow - посему в документации и рекомендуют настоятельно узать wxWindow::Destroy(), реализующий отложенное уничожение объекта.
Каким образом стоит поступать мне - перенаследовать все классы от wxWindow и узать Destroy или есть какой-то другой, способ( может отложенное удаление как то заложенно в сам класс wxEvtHandler ). Вариант с наследованием от wxWindow не очень симпатизирует - все таки не "окна" делаю.
Каким образом стоит поступать мне - перенаследовать все классы от wxWindow и узать Destroy или есть какой-то другой, способ( может отложенное удаление как то заложенно в сам класс wxEvtHandler ). Вариант с наследованием от wxWindow не очень симпатизирует - все таки не "окна" делаю.
-
- Experienced Solver
- Posts: 70
- Joined: Fri Nov 07, 2008 4:25 pm
- Location: Saint-Petersburg, Russia
Как это "к нему"? Падеж может быть, если например кто-то пытается вызвать метод по указателю на удаленный объект. Но при чем здесь очередь сообщений? Если я правильно понимаю, то это может возникать разве что из-за того, что объект был удален, но не изъят из списка обработчиков, в который он был помещен.в очереди сообщений еще могут остаться к нему необработанные сообщения.
Можно пример использования такого класса для ясности?
win xp pro sp3/VS Express 2008/MinGW;
win Vista Ultimate/VS 2005;
Debian Lenny/gcc/cegcc-mingw32ce;
wxWidgets-2.8.9 w/wxWinCE;
win Vista Ultimate/VS 2005;
Debian Lenny/gcc/cegcc-mingw32ce;
wxWidgets-2.8.9 w/wxWinCE;
Вообщем то это я имел ввидуradcapricorn wrote: Если я правильно понимаю, то это может возникать разве что из-за того, что объект был удален, но не изъят из списка обработчиков, в который он был помещен.
Частный пример, на котором падеж:radcapricorn wrote: Можно пример использования такого класса для ясности?
Есть класс, унаследованный от wxEvtHandler. В нем агрегирован объект типа wxSocketBase *. У данного объекта я использую метод SetEventHandler, для того, чтобы отслеживать события, происходящие на сокете. Параметром в SetEventHandler передаю this.
Дальше наибольший интерес представляет деструктор класса:
в котором я вызываю Destroy для объекта сокета( + предварительно вызываю notify(false) для того же объекта сокета).
Если я не вызываю деструктор класса( не уничтожаю объект ) проблем никаких нет, а вот когда вызываю - случаются падежи.
Т.е. действительно подозрения на то, что мой объект не был изьят из списков обработчиков. Как это можно сделать?
-
- Experienced Solver
- Posts: 70
- Joined: Fri Nov 07, 2008 4:25 pm
- Location: Saint-Petersburg, Russia
В случае с wxSocketBase - никак, да это и не нужно. Скорее всего нужно убедиться в том, что объект-агрегат умрет после сокета.
Здесь возможен вариант, что события, сгенерированные сокетом до его удаления по Destroy(), еще будут доставляться (т.к. он "физически" умрет только в слующий idle time). Только вот сам обработчик к этому времени будет уже уничтожен.
В данном случае это чисто мое ИМХО, я просто бегло пробежался по исходникам wxWidgets. Так что могу заблуждаться
Случай действительно интересный. Падежи происходят в деструкторе или "случайно", но после вызова деструктора?
Здесь возможен вариант, что события, сгенерированные сокетом до его удаления по Destroy(), еще будут доставляться (т.к. он "физически" умрет только в слующий idle time). Только вот сам обработчик к этому времени будет уже уничтожен.
В данном случае это чисто мое ИМХО, я просто бегло пробежался по исходникам wxWidgets. Так что могу заблуждаться
Случай действительно интересный. Падежи происходят в деструкторе или "случайно", но после вызова деструктора?
win xp pro sp3/VS Express 2008/MinGW;
win Vista Ultimate/VS 2005;
Debian Lenny/gcc/cegcc-mingw32ce;
wxWidgets-2.8.9 w/wxWinCE;
win Vista Ultimate/VS 2005;
Debian Lenny/gcc/cegcc-mingw32ce;
wxWidgets-2.8.9 w/wxWinCE;
-
- Experienced Solver
- Posts: 70
- Joined: Fri Nov 07, 2008 4:25 pm
- Location: Saint-Petersburg, Russia
Судя по всему, так и есть - остается какая-то связка между сокетом и обработчиком, причем второй удаляется явно раньше первого.
Можно попробовать реализовать Destroy() для обработчика вот так:
Можно попробовать реализовать Destroy() для обработчика вот так:
Code: Select all
wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : 0;
if (traits)
{
traits->ScheduleForDestroy(this);
}
else
{
delete this;
}
win xp pro sp3/VS Express 2008/MinGW;
win Vista Ultimate/VS 2005;
Debian Lenny/gcc/cegcc-mingw32ce;
wxWidgets-2.8.9 w/wxWinCE;
win Vista Ultimate/VS 2005;
Debian Lenny/gcc/cegcc-mingw32ce;
wxWidgets-2.8.9 w/wxWinCE;
Спасибо! Помогло )radcapricorn wrote:Судя по всему, так и есть - остается какая-то связка между сокетом и обработчиком, причем второй удаляется явно раньше первого.
Можно попробовать реализовать Destroy() для обработчика вот так:
Code: Select all
wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : 0; if (traits) { traits->ScheduleForDestroy(this); } else { delete this; }
p.s. В официальный мануалах описание wxAppTraits::ScheduleForDestroy() не нашел, только в хидерах библиотеки непосредственно. Много еще такого скрытого богатсва в wx?
-
- Experienced Solver
- Posts: 70
- Joined: Fri Nov 07, 2008 4:25 pm
- Location: Saint-Petersburg, Russia
m1t0z,
T-Rex,
Насчет Yield() и почему оно не помогает - тут уж не знаю. Будет время - покопаюсь в исходниках "на пощупать".
Да прилично, если в сырцах поковырятьсяp.s. В официальный мануалах описание wxAppTraits::ScheduleForDestroy() не нашел, только в хидерах библиотеки непосредственно. Много еще такого скрытого богатсва в wx?
T-Rex,
Насчет Yield() и почему оно не помогает - тут уж не знаю. Будет время - покопаюсь в исходниках "на пощупать".
win xp pro sp3/VS Express 2008/MinGW;
win Vista Ultimate/VS 2005;
Debian Lenny/gcc/cegcc-mingw32ce;
wxWidgets-2.8.9 w/wxWinCE;
win Vista Ultimate/VS 2005;
Debian Lenny/gcc/cegcc-mingw32ce;
wxWidgets-2.8.9 w/wxWinCE;
- Billy Bones
- In need of some credit
- Posts: 3
- Joined: Mon Nov 13, 2006 7:54 pm
- Location: Moscow, Russia
- Contact:
-
- Experienced Solver
- Posts: 70
- Joined: Fri Nov 07, 2008 4:25 pm
- Location: Saint-Petersburg, Russia
Оживляем тему?
Из (1) следует отсутствие необходимости явного вызова Close().
Из (2) - наличие уже назначенных (до вызова Close()) событий, которые никто вовсе и не прибивает.
Code: Select all
wxSocketBase::Close
void Close()
(1) ...Upon socket destruction, Close is automatically called...
Remark/Warning
(2) Although Close immediately disables events for the socket, it is possible that event messages may be waiting in the application's event queue. The application must therefore be prepared to handle socket event messages even after calling Close.
Из (2) - наличие уже назначенных (до вызова Close()) событий, которые никто вовсе и не прибивает.
win xp pro sp3/VS Express 2008/MinGW;
win Vista Ultimate/VS 2005;
Debian Lenny/gcc/cegcc-mingw32ce;
wxWidgets-2.8.9 w/wxWinCE;
win Vista Ultimate/VS 2005;
Debian Lenny/gcc/cegcc-mingw32ce;
wxWidgets-2.8.9 w/wxWinCE;