Обсуждение статьи "Порядок создания и уничтожения объектов в MQL5"

 

Опубликована статья Порядок создания и уничтожения объектов в MQL5:

Каждый объект, будь то пользовательский объект, динамический массив или массив объектов, имеет свои особенности создания и уничтожения в программе MQL5. Зачастую одни объекты являются частью других объектов, и порядок уничтожения объектов в момент деинициализации становится особенно важен. В этой статье приводятся несколько примеров для понимания механизмов работы с объектами.

Язык MQL5 позволяет писать в стиле объектно-ориентированного программирования (ООП), и это не только открывает новые возможности для создания собственных библиотек, но и позволяет использовать уже готовые, разработанные и протестированные классы других разработчиков. В стандартной библиотеке из поставки терминала MetaTrader 5 уже реализованы сотни классов, которые содержат тысячи методов.

Чтобы успешно использовать все преимущества ООП, необходимо уяснить некоторые тонкости, связанные с созданием и уничтожением объектов в программах на языке MQL5. В Документации кратко описано создание и уничтожение объектов в MQL5, эта статья проиллюстрирует указанный раздел примерами.

Автор: MetaQuotes

 

При первом запуске LocalVar_TestScript_2.mq5 выдаётся только

PO      0       LocalVar_TestScript_2 (EURGBP,M1)       12:08:19        CItem::CItem Constructor
LD      0       LocalVar_TestScript_2 (EURGBP,M1)       12:08:19        CItem::CItem Constructor
HJ      0       LocalVar_TestScript_2 (EURGBP,M1)       12:08:19        CItem::CItem Constructor
DS      0       LocalVar_TestScript_2 (EURGBP,M1)       12:08:19        CItem::CItem Constructor
PH      0       LocalVar_TestScript_2 (EURGBP,M1)       12:08:19        CItem::CItem Constructor
GP      0       LocalVar_TestScript_2 (EURGBP,M1)       12:08:19        CItem::~CItem Destructor
KF      0       LocalVar_TestScript_2 (EURGBP,M1)       12:08:19        CItem::~CItem Destructor
OM      0       LocalVar_TestScript_2 (EURGBP,M1)       12:08:19        CItem::~CItem Destructor
CD      0       LocalVar_TestScript_2 (EURGBP,M1)       12:08:19        CItem::~CItem Destructor
GK      0       LocalVar_TestScript_2 (EURGBP,M1)       12:08:19        CItem::~CItem Destructor

  т.е. без сообщения "delete invalid pointer". После перекомпиляции этого же файла (т.е. после второй по счёту компиляции) выдало вот что:

PQ      0       LocalVar_TestScript_2 (EURUSD,H1)       12:09:12        CItem::CItem Constructor
LH      0       LocalVar_TestScript_2 (EURUSD,H1)       12:09:12        CItem::CItem Constructor
HO      0       LocalVar_TestScript_2 (EURUSD,H1)       12:09:12        CItem::CItem Constructor
DF      0       LocalVar_TestScript_2 (EURUSD,H1)       12:09:12        CItem::CItem Constructor
PL      0       LocalVar_TestScript_2 (EURUSD,H1)       12:09:12        CItem::CItem Constructor
GR      0       LocalVar_TestScript_2 (EURUSD,H1)       12:09:12        CItem::~CItem Destructor
KK      0       LocalVar_TestScript_2 (EURUSD,H1)       12:09:12        CItem::~CItem Destructor
OP      0       LocalVar_TestScript_2 (EURUSD,H1)       12:09:12        CItem::~CItem Destructor
CF      0       LocalVar_TestScript_2 (EURUSD,H1)       12:09:12        CItem::~CItem Destructor
GO      0       LocalVar_TestScript_2 (EURUSD,H1)       12:09:12        CItem::~CItem Destructor
PH      1       LocalVar_TestScript_2 (EURUSD,H1)       12:09:12        敤敬整渠湯搠湹浡捩漠橢捥t
RP      1       LocalVar_TestScript_2 (EURUSD,H1)       12:09:12        敤敬整渠湯搠湹浡捩漠橢捥t
DH      1       LocalVar_TestScript_2 (EURUSD,H1)       12:09:12        敤敬整渠湯搠湹浡捩漠橢捥t
FP      1       LocalVar_TestScript_2 (EURUSD,H1)       12:09:12        敤敬整渠湯搠湹浡捩漠橢捥t
HH      1       LocalVar_TestScript_2 (EURUSD,H1)       12:09:12        敤敬整渠湯搠湹浡捩漠橢捥t
С момента опубликования статьи реакция терминала на удаление некорректных указателей  была  изменена? ХР, 32
 
Yedelkin:

При первом запуске LocalVar_TestScript_2.mq5 выдаётся только

  т.е. без сообщения "delete invalid pointer". После перекомпиляции этого же файла (т.е. после второй по счёту компиляции) выдало вот что:

С момента опубликования статьи реакция терминала на удаление некорректных указателей  была  изменена? ХР, 32
Спасибо за сообщение. Исправлено. Поведение изменилось, теперь сообщение "delete invalid pointer" выдаётся только при компиляции под отладку.
 

mql5:
Спасибо за сообщение. Исправлено. Поведение изменилось, теперь сообщение "delete invalid pointer" выдаётся только при компиляции под отладку.

ОК, напрашивается пожелание о внесении уточнения в статью.
 

А почему вот эта строчка приводит к запуску конструктора:

 CItem* array1[5];

 , а вот эта нет:

CObjectC *pObjectC;
?
 
Оператор new нужен только чтоб класс был динамическим? Но если динамический массив - это "массив с неуказанным значением в первой паре квадратных скобок", то динамичекий класс это что?
Документация по MQL5: Основы языка / Типы данных / Объект динамического массива
Документация по MQL5: Основы языка / Типы данных / Объект динамического массива
  • www.mql5.com
Основы языка / Типы данных / Объект динамического массива - Документация по MQL5
 
Burgunsky:

А почему вот эта строчка приводит к запуску конструктора:

Проверил, никакого вызова конструктора не происходит, приложите весь код пожалуйста
 
Burgunsky:

А почему вот эта строчка приводит к запуску конструктора:  CItem* array1[5];,

а вот эта нет: CObjectC *pObjectC;    ?

Я понял так, что строчка

CItem* array1[5];

сама по себе не приводит к запуску конструктора. Вот более полный код из статьи:

void OnStart()
  {
//--- объявим первый массив указателей на объект
   CItem* array1[5];
//--- объявим второй массив указателей на объект
   CItem* array2[5];
//--- теперь заполним массивы в цикле
   for(int i=0;i<5;i++)
     {
      //--- указатель для первого массива создадим оператором new
      array1[i]=new CItem;
      //--- указатель для второго массива скопируем из первого массива
      array2[i]=array1[i];
     }
Конструктор вызывается не при объявлении первого массива указателей, а при заполнении этого массива в цикле с помощью оператора new.
 

 
Burgunsky:
Оператор new нужен только чтоб класс был динамическим? Но если динамический массив - это "массив с неуказанным значением в первой паре квадратных скобок", то динамичекий класс это что?
Я понял так, что слово "динамический" в программировании является многозначным. Применительно к классам идёт противопоставление: "автоматически созданный объект" vs "динамически созданный объект". Различие между ними примерно такое же, как между переменными, объявленными на глобальном уровне, и переменными, объявленными на локальном уровне. Иными словами, "динамически созданный объект" - это объект, созданный "на время", время жизни - от момента создания оператором new до момента удаления оператором delete. 
 

Но всеравно остались вопросы:

В чем смысл создания динамического объекта через оператор new?

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

При динамическом создании объекта, объект класса создается в памяти(в куче) при этом задействуя  менеджер памяти ОС процесс происходит медленнее.

Вот вопрос: если автоматическое создание быстрее то почему тогда создаются динамические объекты? Чтобы стек не переполнился?

 

Добрый день,


Ни как не могу понять этот участок:

//--- этот блок не выполнится, если execute==false
   if(execute)
     {
      CObjectB objB;
     }
//--- этот блок выполнится, если execute==false
   if(!execute)
     {
      CObjectC objC;
     }

В начале кода задается что execute = false. Словами: execute равно false.

Первый ЕСЛИ: если значение execute ИСТИНА, то блок должен выполниться. Но в комменте написано что он НЕ выполниться если ИСТИНА и перейдет к следующему.

Второй ЕСЛИ: если значение execute ЛОЖЬ, то блок выполнется. Но опять же в комменте написано что блок ВЫПОЛНИТЬСЯ если ИСТИНА.

Я полагала что ! - это символ отрицания.

Где ошибка в моих рассуждениях?