#c #wxwidgets
#c #wxwidgets
Вопрос:
Я пытаюсь изучить wxWidgets, но я застрял на моменте, которому я не могу найти объяснения нигде в документации. Я пытаюсь понять эту минимальную программу wxWidgets:
#include <wx/wx.h>
class MyApp : public wxApp
{
virtual bool OnInit();
};
IMPLEMENT_APP(MyApp)
bool MyApp::OnInit()
{
wxFrame *frame = new wxFrame(NULL, -1, _("Hello World"), wxPoint(50, 50),
wxSize(450, 350));
frame->Show(true);
return true;
}
В частности, почему это frame
не протекает? Когда это будет выпущено и чья ответственность лежит на is? В обычной программе указатель, который ни на что не передается и который выходит за пределы области видимости без удаления, почти наверняка является утечкой, но, по-видимому, в wxWidgets это не так.
Комментарии:
1. Он может зарегистрироваться в фреймворке и быть удален при закрытии окна.
2. @Xeo Этот код взят непосредственно из примера кода в документации (сокращен для наглядности). Я не могу найти ни одного примера кода, в котором фрейм был бы удален, поэтому я предполагаю, что он каким-то образом удаляется. В то же время я не могу найти ничего в документации, в которой конкретно говорится, что фрейм будет удален, поэтому я надеюсь, что у кого-нибудь на SO есть полная история.
3. Ого — я нашел полный ответ здесь .
Ответ №1:
Очистка обсуждается здесь:http://docs.wxwidgets.org/2.9.2/overview_windowdeletion.html
Ответ №2:
Смотрите примечание в примере Hello World на wxWidgets wiki:
http://wiki.wxwidgets.org/Hello_World
«Возможно, вам интересно, почему переменная frame нигде не удаляется. Установив фрейм в качестве верхнего окна приложения, приложение удалит фрейм для нас (более подробное объяснение см. в разделе Предотвращение утечек памяти).»
Однако опубликованный вами код не вызывает SetTopWindow()
так, как это делает код из wiki. Итак, я предполагаю, что это приведет к утечке.
Комментарии:
1. Я не думаю, что это на самом деле правильно. В документации указано, что «Вам не обязательно устанавливать верхнее окно; это всего лишь удобство». Я только что нашел документацию для wxTopLevelWindow , в которой говорится, что «экземпляры wxTopLevelWindow управляются wxWidgets во внутреннем списке окон верхнего уровня».
2. Хорошо, хорошо, именно из-за высокого уровня не происходит утечки … и если подразумевается, что все wxFrames являются фреймами верхнего уровня, то я предполагаю, что так оно и есть. Qt, кстати, так не работает. Я добавлю, что, если вы не пробовали Qt, он спроектирован (и документирован) намного лучше, чем wxWidgets: doc.qt.nokia.com/latest/tutorials-widgets-toplevel.html
3. Я посмотрел на QT, но его отсутствие безопасности исключений заставляет меня считать его непригодным для любого приложения, для которого корректность является высоким приоритетом.
4.Какое свойство wxWidgets является безопасным для исключений, которое небезопасно в Qt? Из часто задаваемых вопросов по wxWidgets: «Сама библиотека wxWidgets, к сожалению, не защищена от исключений (поскольку ее начальная версия, безусловно, предшествует добавлению исключений в язык C )». wxwidgets.org/docs/faqgen.htm#exceptions
5. Мне тоже не очень нравятся wxWidgets.
Ответ №3:
Утечка памяти происходит, когда программа продолжает выделять память и никогда не освобождает ее. В конечном итоге такой программе не хватит новой памяти для выделения и остановки.
MyApp::OnInit() вызывается один раз при запуске программы. Память для фрейма выделяется один раз и остается выделенной до завершения программы, что именно то, что вам нужно, чтобы произошло. Утечки памяти нет, потому что новый wxFrame в OnInit() вызывается только один раз.
Вполне может быть, что wxWidgets регистрирует указатель wxFrame и следит за его исправлением, если программа завершает работу корректно. Это было бы неплохо, но не имеет практического значения.
Комментарии:
1. Есть практическая разница. Прежде всего, если вы просто позволите программе завершиться выдающимся динамическим объектом… деструктор никогда не запускается. Даже если у вас есть тривиальный деструктор, у вас все еще есть проблема в том, что трудно отличить «целенаправленную» утечку памяти такого рода от «случайной», если вы используете Valgrind или другой инструмент отчетности.