Вопросы по ООП в MQL5 - страница 8

 
Igor Makanu:

не пишите delete - все будет корректно работать, этот грех (я про суеверие )) ) на себя возьмет терминал, и будет  бормотать в логе "48 bytes of leaked memory" то "2 objects of type CX left" и "undeleted objects left"

ЗЫ: в шаблоне создания индикатора нет Deinit() - это напрягает

А почему бы не создать объект, а не указатель? Тогда и бормотать не будет - подсистема терминала его отследит и прибьёт когда нужно.

 
Dmitry Fedoseev:

Работать будет без delete, а толку. А вот берет ли терминал на себя эту проблему? Он только сообщает об утечки памяти, но не уделяет же объекты.

Терминал возьмёт на себя удаление объектов, созданных по new в случае, если указатели на них сложены в известный терминалу объект, например ArrayObj, List, etc...

 
Artyom Trishkin:

А почему бы не создать объект, а не указатель? Тогда и бормотать не будет - подсистема терминала его отследит и прибьёт когда нужно.

потому что https://www.mql5.com/ru/forum/85652/page7#comment_12329866

Artyom Trishkin:

Терминал возьмёт на себя удаление объектов, созданных по new в случае, если указатели на них сложены в известный терминалу объект, например ArrayObj, List, etc...

не всегда удобно не контролируемое уничтожение, но нужно будет проверить, может быть я ошибаюсь - редко пользуюсь CObject

 

Ну это совсем по-моему частный и гротескно-упрощенный случай. Создавать абсолютно неизменяемый объект, чтобы для изменения значения его полей нужно было прибивать его и рождать новый...

А если нужно, изменив пару полей объекта, оставить другие поля с нужной информацией? IMHO - лучше позаботиться об интерактивности и управляемости каждого из объектов (благо наследование есть), чем сидеть с ружьём и стрелять по кроликам на каждом чихе.

Хотя, справедливости ради - иногда быстрее прибить и создать новый, чем искать требуемый среди большого количества и менять его. Ну это конечно если не организована прямая адресация на него...

 
Artyom Trishkin:

Ну это совсем по-моему частный и гротескно-упрощенный случай. Создавать абсолютно неизменяемый объект, чтобы для изменения значения его полей нужно было прибивать его и рождать новый...

А если нужно, изменив пару полей объекта, оставить другие поля с нужной информацией? IMHO - лучше позаботиться об интерактивности и управляемости каждого из объектов (благо наследование есть), чем сидеть с ружьём и стрелять по кроликам на каждом чихе.

Хотя, справедливости ради - иногда быстрее прибить и создать новый, чем искать требуемый среди большого количества и менять его. Ну это конечно если не организована прямая адресация на него...

хм, ну ты загнул.... так, но не так )))

как удобно, так и нужно пользоваться! - а вот эти примеры из "первого учебника по С++" можно всю жизнь тянуть в своем опыте.... как пример, я разобрал приличную часть кодов @fxsaber и заставил себя пользоваться по максимуму #define - коды стали не только короче, но и действительно более читаемыми и исключены опечатки - в книгах по С++ много этому учат?      ;)


Artyom Trishkin:

Хотя, справедливости ради - иногда быстрее прибить и создать новый, чем искать требуемый среди большого количества и менять его. Ну это конечно если не организована прямая адресация на него... 

ну и про книжные основы... по правилам "хорошего тона" в программировании положено: объявил переменную - сразу проинициализируй (так достигается исключение багов при отладке), в ООП для этих целей служит конструктор - создал обьект, будь добр все проинициализируй

если "тянуть за собой простой обьект весь код", то будет необходим метод который будет переинициализирвоать все поля класса - зачем дублировать это? - убил/создал = результат.... но опять же дело вкуса и религии

 
Igor Makanu:

потому что https://www.mql5.com/ru/forum/85652/page7#comment_12329866

не всегда удобно не контролируемое уничтожение, но нужно будет проверить, может быть я ошибаюсь - редко пользуюсь CObject

Но списками-то пользуетесь. А там - то же самое. Ну если только для списка не сброшен флаг управления памятью FreeMode() - в этом случае терминал не будет отслеживать - всё на себя берёт пользователь. Но эта ситуация нужна для того, чтобы можно было менять, удалять, сортировать и что-либо ещё делать с копией списка - ведь создаётся список с указателями на объекты, и если создать новый список-копию одного из списков, и начать изменять в новом списке объекты (а там указатели на объекты), то и в оригинальном списке будут объекты изменены (потомучто работаем с указателями). Вот чтобы оставить оригинал, и поизгаляться над его копией, то нужно сбросить для копии флаг управления памятью: FreeMode(false) - тогда эта копия станет независимой копией, и можно будет смело в ней работать с объектами, не затрагивая при этом оригинал. И помнить, что раз отцепили список-копию от подсистемы терминала, то и за удаление объектов списка теперь ответственны мы сами. Можно либо отслеживать его и удалять в OnDeinit(), то это в самом простом случае, и если список-копия нам заранее известен, либо создать объект-список, в который всегда размещать вновь создаваемые заранее не известные списки с флагом ручного управления памятью. Тогда терминал будет отслеживать этот объект-список, и корректно удалять сложенные в него списки.

 
Artyom Trishkin:

Терминал возьмёт на себя удаление объектов, созданных по new в случае, если указатели на них сложены в известный терминалу объект, например ArrayObj, List, etc...

Тогда и сообщения об утечке не будет.

 
Dmitry Fedoseev:

Тогда и сообщения об утечке не будет.

Да, не будет. Потому что и утечки не будет

Мы же, если создали где-то новый объект и получили на него указатель, то должны удалить этот объект по данному указателю. Значит - указатель нужно отслеживать. Вот для этого и очень хорошо подходят списки или массивы указателей на объекты, предлагаемые в СБ. Но можно и самому озаботиться отслеживанием и контролем за вновь создаваемыми объектами. Но, как по мне, то а зачем писать тонны кода, если он уже предоставлен?

 
Artyom Trishkin:

 то должны удалить этот объект по данному указателю.

Но, как по мне, то а зачем писать тонны кода, если он уже предоставлен? 

речь о каких тоннах идет? все что проглядели, обо всем сообщит терминал, место где удалять тоже известно - OnDeint() .... беседа свелась к обсуждению  сферического коня в вакууме? )))

 
Igor Makanu:

хм, ну ты загнул.... так, но не так )))

как удобно, так и нужно пользоваться! - а вот эти примеры из "первого учебника по С++" можно всю жизнь тянуть в своем опыте.... как пример, я разобрал приличную часть кодов @fxsaber и заставил себя пользоваться по максимуму #define - коды стали не только короче, но и действительно более читаемыми и исключены опечатки - в книгах по С++ много этому учат?      ;)


ну и про книжные основы... по правилам "хорошего тона" в программировании положено: объявил переменную - сразу проинициализируй (так достигается исключение багов при отладке), в ООП для этих целей служит конструктор - создал обьект, будь добр все проинициализируй

если "тянуть за собой простой обьект весь код", то будет необходим метод который будет переинициализирвоать все поля класса - зачем дублировать это? - убил/создал = результат.... но опять же дело вкуса и религии

Я говорил не о полной переинициализации объекта, а о частичной - когда пару полей нужно поменять, а остальные пара десятков хранят пока ещё нужную информацию... Тут "хошь-не хошь", а методы изменения полей нужны. Если - опять-таки - не говорить о простом объекте, где одно поле. При наличии двух и более - уже может потребоваться менять одно, оставляя другие неизменными.

Но может мы о разных вещах говорим?

Причина обращения: