Ошибки, баги, вопросы - страница 453

 
Interesting:

Не создавайте динамических объектов - не придется использовать now и всего прочего что связано с этими объектами (Правда тогда Вы не сможете много чего сделать).

Понять то видимо хочется не то в чем смысл now, а в чем смысл работы с динамическими объектами...   

                                      

   ////////////////////////////////////////    ДАЛЬШЕ МОЙ ТЕКСТ (НЕ МОГУ ВЫЙТИ ИЗ ЦИТАТЫ) :)   ////////////////////////////////////////////////////////////// 

void OnStart()
  {
//---
primer obekt;
obekt.f1();
  }
//+------------------------------------------------------------------+
class primer
   {
      public:
      void f1();

      primer();
   };
  

primer::primer()
   {
      Alert("Я думаю что и здесь инициализация только в момент создания");
   };

primer::f1()
   {
      int l[];
      ArrayResize(l,3);
      l[0]=87;
      l[1]=67;
      l[2]=57;
      ArrayResize(l,5);
      l[3]=47;
      l[4]=37;
      Alert(l[0],"   ",l[1],"   ",l[2],"   ",l[3],"   ",l[4]);
   }; 

Такой код не дает ошибку, а масив динамический. Почему???? 

А если нужно уничтожить то: 

      primer obekt;
      obekt.f1();


}

  

Создается впечатление что взяли С++ испортили работу с адресами  и засунули в MQL

 

 

220Volt:

ДАЛЬШЕ МОЙ ТЕКСТ (НЕ МОГУ ВЫЙТИ ИЗ ЦИТАТЫ) :)

Такой код не дает ошибку, а масив динамический. Почему????

1. А почему он должен выполняться с ошибкой???

а) Объект создается автоматически (это обусловлено методом объявления экземпляра объекта в OnStart), автоматически же и удаляется

primer  obekt1;   //Конструктор будет вызван автоматически уже на этой строчке
primer *obekt2; //Указатель на динамический объект

void OnStart()
{
obekt2 = new primer; //Конструктор выполняется вот тут 

obekt.f1();

delete(obekt2); //Тут выполняется деструктор (отсутствие delete приведет к утечки памяти в момент завершения работы скрипта)
}

Что касается объектов, то их экземпляры могут создаваться автоматически или динамически. В первом случае конструктор обычно выполняется в момент инициализации, во втором только после использования оператора new.

б) В f1() тоже по логике вещей ошибок быть не должно (хотя лично я реализацию бы сделал иную).

Что касается динамических массивов. Отличие их от статических в том что у таких массивов заранее не известна размерность, а значит перед работой с таким массивом ее нужно указать при помощи ArrayResize (указывается новый размер в первом измерении массива). Важно отметить что элементы массива нумеруются с 0.

2. Если Вас интересует работа именно с динамическими объектами внимательно изучите вот этот пример - Теетрис (правда что он делает на старом форуме понять до сих пор не могу)...

 

Извените за назойливость, просто очень хочется разобраться. Изложу свое виденье, в чем я ошибаюсь???

Если посмотреть на С++ запись (у нас есть объявленный класс primer) 

primer *ukazatel=new primer; 

говорит что ukazatel содержит адрес в памяти где хранится наш объект, копия класса primer. Из MQL адреса убраны, и ukazatel содержит дескриптор объекта. Что нам это дает?? Единственная разница которую я заметил- если внутри блока объявили через new объект и забыли до завершения блока использывать delete, то удален объект будет только тогда когда завершится программа. И после выхода из блока связь с этим объекто через дескриптор будет утеряна.

      У меня была мысль что если объявили через new, то память под объект выделяется динамически (т.е. у него есть возможность увеличевать свой размер), а если без new, то у объекта могут быть только статические переменные. Но мое предположение не подтвердилось (скрипт который я выкладывал раньше, объект объявлен не через new, но он  имеет дело с динамической переменной).

     И вот после всех этих страстей я нахожусь в не очень красивой ситуации, и совсем не понимаю какая разница с new или без него??? А если компилятор сам там что-то исправляет, то зачем мне вообще париться??? 

      

Документация по MQL5: Основы языка / Переменные / Статические переменные
Документация по MQL5: Основы языка / Переменные / Статические переменные
  • www.mql5.com
Основы языка / Переменные / Статические переменные - Документация по MQL5
 

Даже пытался сделать что-то вроде того что описано в документации (чтобы что-то выяснить про new) :

switch(5)

   {

         case 5: m_shape=new CTetrisShape1;                    // такой вариант вообще не прокатывает (а это из документации!!!) только так  

                                                                                                                                                                                 ( m_shape=new CTetrisShape1; )

   } 

и теперь мы не сможем обратиться к объекту m_shape.___   , будет выведена ошибка

 

220Volt:

И вот после всех этих страстей я нахожусь в не очень красивой ситуации, и совсем не понимаю какая разница с new или без него??? А если компилятор сам там что-то исправляет, то зачем мне вообще париться???    

Экземпляры объектов создаются динамически с использование оператора new если (и для этого я и просил посмотреть пример с Тетрисом):

1. Заранее не известно количество экземпляров объектов (но предполагается что их будет всегда больше одного);

2. Если нужно создать массив указателей на "разношерстные" объекты, которые имеют одного предка;

3. Если предполагается что объект (верней указатель на этот объект) будет задействован в качестве параметра для процедуры или функции (возможно необходимо передать его в библиотеку);

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

5. Существует еще много задач которые решаются путем применения динамически созданных обетов и указателей на них. 

 
220Volt:

Даже пытался сделать что-то вроде того что описано в документации (чтобы что-то выяснить про new) :

........................

и теперь мы не сможем обратиться к объекту m_shape.___   , будет выведена ошибка

Вообще-то в примере самого Тетриса это вот таким образом реализовано (замете, что в Вашем случае упущен оператор break)

   switch(nshape)
     {
      case 0: m_shape=new CTetrisShape1; break;
      case 1: m_shape=new CTetrisShape2; break;
      case 2: m_shape=new CTetrisShape3; break;
      case 3: m_shape=new CTetrisShape4; break;
      case 4: m_shape=new CTetrisShape5; break;
      case 5: m_shape=new CTetrisShape6; break;
      case 6: m_shape=new CTetrisShape7; break;
     }

При этом не забываем проверять указатель на равенство NULL

 if(m_shape!=NULL)
 {
//С указателем можно работать
 }
 

 

Interesting  благодарю за помощь
 

Разработчикам.

В документации укажите плиз в "явном виде" все то что в тестере либо не работает, либо работает с определенными особенностями (что-бы лишних вопросов не возникало).

Например следует в явно указать на особенности работы с локальным временем и временем по GMT (приравнены к серверному времени), а также проблематичность получить от TimeGMTOffset ожидаемого результата.

 

Кто в курсе -- есть нормальный способ перевести юникодный массив чаров в строку?

 
TheXpert:

Кто в курсе -- есть нормальный способ перевести юникодный массив чаров в строку?

Как мне представляется придется переводить каждый элемент массива по отдельности.
Документация по MQL5: Основы языка / Переменные
Документация по MQL5: Основы языка / Переменные
  • www.mql5.com
Основы языка / Переменные - Документация по MQL5