Russian Qt Forum
Январь 18, 2018, 03:18 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 2 [3]   Вниз
  Печать  
Автор Тема: как правильно работать с Qt, чтобы не было утечек памяти?  (Прочитано 20297 раз)
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3857



Просмотр профиля
« Ответ #30 : Август 27, 2015, 14:15 »

Согласен, что зависит от задачи. Но таких задач очень мало Улыбающийся
Нет. Такие задачи практически все.
Записан
Ilia_Ivanov
Гость
« Ответ #31 : Сентябрь 23, 2015, 19:03 »

1. Покажите пример того, как вы обычно создаёте новый класс, новый объект этого класса, как вызываете метод объекта этого класса и как удаляете объект этого класса.

Чуть раньше у меня было всё просто. Выясняем необходимость в объекте. Думаем минут пятнадцать, а правда ли объект нам необходим. Идем в Visual Studio, добавляем руками хедер, не забыв указать папку Include в папке проекта. Сразу добавляем в хедер гварды через Visual Assist, чтобы не было проблем, через контекстное меню. Дописываем после гвардов пустую строку, комментарий, зачем класс нужен, включаем TApplication.h - это основной хедер приложения. В нем уже включены все контейнеры Qt и много мелочей, дефайны разные, структуры, энумы. Пишем руками заголовок класса, если нужно унаследоваться, возвращаемся назад и дописываем хедер с классом, от которого наследование. Для всех агрегатированных членов-указателей пишем forward declarations, хедеры включаем в cpp-шник нашего класса. После открывающей { пишем или не пишем Q_OBJECT, если нет, то класс не Qt-шный, просто Visual C++. Сразу пишем каркас класса - ключевые слова protected, public, дефолтный конструктор, конструктор от QObject(или QWidget) и виртуальный деструктор. Пишем в секцию public пару методов, какие нужны в первую очередь. Делаем в Visual Assist Create Implementations, снимаем ненужные галочки, получаем реализацию всех методов. Дописываем реализацию и новые методы. Так всё было, но теперь по-другому! Пришла страшная информация, что без юнит-тестов проект обречён. Понял, почему прошлые проекты не доходили до конца, и перешел на TDD(тестирование через разработку). Теперь нужно сначала написать тесты, которые покрывают функциональность класса, по методу красный-зеленый-рефакторинг. Сначала пишем тест через QTest фреймворк, добиваемся, чтобы тест не прошёл, потом пишем класс по имеющимся требованиям, попутно очень тяжело и долго думаем, как так написать, чтобы конструкция вообще заработала. Потому что если без тестов всё как-нибудь поднимется и потом упадёт, то с тестами при ошибочной архитектуре даже не взлетит.
По отлову ошибок. 50 процентов рассчитываю отловить юнит-тестами, остальное дебагом. У меня однопоточка. Я установил кешер буфера обмена windows, прилепил его desk pin-ом на самый верх стопки окон. Очень удобно, но требует серьезного сосредоточения. Идём дебаггером, подозрительные места копируем, после закрытия программы имеем список багов и глюков, исправляем их.
По поводу утечек памяти. Нужно просто грамотно писать код. Запрещено: арифметика указателей полностью, сырые массивы типа int* = new int[5], расползание указателей. Разрешены: stl и qtl, массивы с контролем границ, умные указатели, создание как инициализация. Там еще много требований, всего не перечислишь. Смысл такой - нет этих опасных мест, нет утечек памяти. Без них можно и нужно обходиться. Как в C#.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 9879


Просмотр профиля
« Ответ #32 : Сентябрь 24, 2015, 10:15 »

Так всё было, но теперь по-другому! Пришла страшная информация, что без юнит-тестов проект обречён. Понял, почему прошлые проекты не доходили до конца, и перешел на TDD(тестирование через разработку). Теперь нужно сначала написать тесты, которые покрывают функциональность класса, по методу красный-зеленый-рефакторинг. Сначала пишем тест через QTest фреймворк, добиваемся, чтобы тест не прошёл, потом пишем класс по имеющимся требованиям, попутно очень тяжело и долго думаем, как так написать, чтобы конструкция вообще заработала. Потому что если без тестов всё как-нибудь поднимется и потом упадёт, то с тестами при ошибочной архитектуре даже не взлетит
Долго, но, увы - безуспешно, я пытался выяснить в чем же прелести TDD здесь. Предложил показать преимущества этого подхода на простой студенческой задаче (парсинг obj файла). Ничего конкретного не увидел, только слова "ах как это хорошо". Жевать это все снова уже неинтересно

По поводу утечек памяти. Нужно просто грамотно писать код. Запрещено: арифметика указателей полностью, сырые массивы типа int* = new int[5], расползание указателей. Разрешены: stl и qtl, массивы с контролем границ, умные указатели, создание как инициализация. Там еще много требований, всего не перечислишь. Смысл такой - нет этих опасных мест, нет утечек памяти. Без них можно и нужно обходиться. Как в C#.
Глупость начальства повторять необязательно  Улыбающийся

Записан
Bepec
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 7591


W7 x64, Qt SDK 4.7.2, Руки v1.5


Просмотр профиля
« Ответ #33 : Сентябрь 24, 2015, 10:39 »

По поводу этих ограничений - работал одно время с коллегой, профи в С++. Ему поставили задачу - написать программу на C#. Да да, чтобы не было утечек, чтобы сборщик всё убирал и прочее.
У него ушло 2 дня на то, чтобы в C# был отключен сборщик, появилась арифметика указателей и С# оказался максимально приближен к С++ Улыбающийся

При желании можно вообще пользоваться только безопасными методиками разработки. Вот только такие пути ведут в тупик трудноподдерживаемого кода Веселый
Записан

"Мастер простых решений" Ɋt

чОрный список: Spark
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3857



Просмотр профиля
« Ответ #34 : Сентябрь 24, 2015, 10:43 »

Глупость начальства повторять необязательно  Улыбающийся
А в чем глупость начальства? В том, что они хотят обезопасить свой проект от кучи средних программистов, которые его делают?
Поэтому, проще заставить этих обезьян использовать нормальные средства не допускающие утечек в принципе, чем получить не работоспособный проект после нескольких лет разработки, потратив большую часть бюджета на з/п этих "специалистов".
Записан
Bepec
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 7591


W7 x64, Qt SDK 4.7.2, Руки v1.5


Просмотр профиля
« Ответ #35 : Сентябрь 24, 2015, 19:51 »

Old, затраты и сложность реализации из-за этих "обезопасностей" повышаются раз в 10-15, на мой взгляд.
Более того целый слой возможностей языка делается недоступным.
А получаем мы "отсутствие опасных мест", которые средним программистом обходятся на раз два.

Очень похоже на лечение сыпи методом ампутации. И проблема вроде решена, и сыпи на теле уже не осталось, однако сыпь (утечки) всё равно могут быть Веселый

PS не верю в прекращение использования таких мест. Тот же winapi полное нарушение всех правил. Т.е. мы и взаимодействовать не можем Веселый

Записан

"Мастер простых решений" Ɋt

чОрный список: Spark
Ilia_Ivanov
Гость
« Ответ #36 : Сентябрь 24, 2015, 20:02 »

А получаем мы "отсутствие опасных мест", которые средним программистом обходятся на раз два.

Это про утечки памяти? Без целого дня копания с дебаггером ее часто не обнаружить. Я лучше буду обходить опасные места и лишаться некоторых возможностей языка, чем получу программу с такой ошибкой.

Я почти не взаимодействую с winapi. Winapi - это ад, чем меньше его будет, тем лучше. Ему не помогут никакие средства, это не повод вводить небезопасную технику работы.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3857



Просмотр профиля
« Ответ #37 : Сентябрь 24, 2015, 20:07 »

Old, затраты и сложность реализации из-за этих "обезопасностей" повышаются раз в 10-15, на мой взгляд.
Какие затраты и сложности? Вы о чем? Улыбающийся

Более того целый слой возможностей языка делается недоступным.
Что это за слой такой? Улыбающийся

А получаем мы "отсутствие опасных мест", которые средним программистом обходятся на раз два.
Ну конечно. Улыбающийся
Обойти "опасное место" в программе состоящей из главного окна и диалога не велика доблесть. Улыбающийся

PS не верю в прекращение использования таких мест. Тот же winapi полное нарушение всех правил. Т.е. мы и взаимодействовать не можем Веселый
Это никак не связано с winapi. Взаимодействуйте по полной. Улыбающийся
Записан
Bepec
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 7591


W7 x64, Qt SDK 4.7.2, Руки v1.5


Просмотр профиля
« Ответ #38 : Сентябрь 24, 2015, 22:05 »

Затраты на "а как сделать вот тут, чтобы не использовать обычные указатели, массивы и прочее".
Слой называется - прямое управление памятью, работа с указателями и массивами.
Обходятся при правильной архитектуре спокойно.
Как вы будете взаимодействовать с WinApi, если для него нужно выделять массивы, передавать тупые указатели и работать с памятью. Т.е. весь код работы с winapi оказывается за пределами этих правил.
Записан

"Мастер простых решений" Ɋt

чОрный список: Spark
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3857



Просмотр профиля
« Ответ #39 : Сентябрь 24, 2015, 22:14 »

Затраты на "а как сделать вот тут, чтобы не использовать обычные указатели, массивы и прочее".
Нет здесь никаких затрат. Это все известно.

Слой называется - прямое управление памятью, работа с указателями и массивами.
Он не куда не девается, а прячется за удобными обертками.

Обходятся при правильной архитектуре спокойно.
Обходятся при правильной архитектуре с кучей ограничений и кастылей.
Именно поэтому лет 20 назад придумали умные указатели, которые все это решают.

Как вы будете взаимодействовать с WinApi, если для него нужно выделять массивы, передавать тупые указатели и работать с памятью. Т.е. весь код работы с winapi оказывается за пределами этих правил.
Что за ерунда. Умные указатели никак с этим не пересекаются. А то что вы всегда выделяете массивы через new, говорит только о вашей квалификации. Подмигивающий
C winapi можно работать совсем без new.

И кстати, а какие функции winapi требуют обязательно выделять блоки на куче? Можно мне показать хотя бы 10 таких? Улыбающийся
« Последнее редактирование: Сентябрь 24, 2015, 23:14 от Old » Записан
Ilia_Ivanov
Гость
« Ответ #40 : Сентябрь 24, 2015, 22:29 »

Ок, соглашаюсь и покидаю тему, не буду спорить. Всем доброго вечера.
Записан
Bepec
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 7591


W7 x64, Qt SDK 4.7.2, Руки v1.5


Просмотр профиля
« Ответ #41 : Сентябрь 25, 2015, 05:50 »

Присоединюсь, спор бессмысленен после слов
Цитировать
Именно поэтому лет 20 назад придумали умные указатели, которые все это решают.
.
Всё решают за нас, печаль.
Записан

"Мастер простых решений" Ɋt

чОрный список: Spark
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 9879


Просмотр профиля
« Ответ #42 : Сентябрь 25, 2015, 11:20 »

Я почти не взаимодействую с winapi. Winapi - это ад, чем меньше его будет, тем лучше. Ему не помогут никакие средства, это не повод вводить небезопасную технику работы.
Следуя этой логике следующим в "списке неиспользуемых" должен быть Qt - ведь хотя бы те же виджеты (о ужас!) просто указатели. что совершенно НЕБЕЗОПАСНО!!!  Улыбающийся

Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3857



Просмотр профиля
« Ответ #43 : Сентябрь 25, 2015, 11:45 »

Следуя этой логике следующим в "списке неиспользуемых" должен быть Qt - ведь хотя бы те же виджеты (о ужас!) просто указатели. что совершенно НЕБЕЗОПАСНО!!!  Улыбающийся
Ну это как написать. Улыбающийся
Цитата из вашего букваря:
Код
C++ (Qt)
   const QWidget *const p = new QWidget();
   // is equivalent to:
   const QScopedPointer<const QWidget> p(new QWidget());
 
   QWidget *const p = new QWidget();
   // is equivalent to:
   const QScopedPointer<QWidget> p(new QWidget());
 
   const QWidget *p = new QWidget();
   // is equivalent to:
   QScopedPointer<const QWidget> p(new QWidget());
 
Записан
Страниц: 1 2 [3]   Вверх
  Печать  
 
Перейти в:  

Страница сгенерирована за 0.095 секунд. Запросов: 22.