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

 
Igor Makanu:

 typedef это тема, пробовал, но тож не очень пошло, нужно еще разбираться где накосячил, должно и с помощью typedef мой пример работать!

Код, который я написал выше, должен работать. Хотел было у себя проверить, но не судьба: =)))))))))))


(билд 1961)

 
Igor Makanu:

typedef это тема, пробовал, но тож не очень пошло, нужно еще разбираться где накосячил, должно и с помощью typedef мой пример работать!

А можете сделать проще и изящее - без лишних скобок и указателей - (и компилируется без странных ошибок))))

#property strict

class CObject{ };
class CMyclass: public CObject {
  public: CMyclass *operator[] (CObject*p){ CMyclass*r = dynamic_cast<CMyclass*>(p); 
                                return CheckPointer(r)!=POINTER_INVALID?r:NULL; }
          int f(){ return 1; } 
} my ;

void OnStart()
{
  CObject*co=new CMyclass;
  
  my[co].f();
}
 
Ilya Malev:

А можете сделать проще и изящее - без лишних скобок и указателей - (и компилируется без странных ошибок))))

не прокатит для моего случая Ваш пример, у меня обьекты динамически создаются, я даже имя им не присваиваю, а Ваш пример через обращение к имени указателя, вот так пробовал, не пропускает компилятор:  '[' - name expected tst_cast.mq4 32 15


#property strict
#include <Object.mqh>
#include <Arrays\List.mqh>
//+------------------------------------------------------------------+
class CMyclass:public CObject
  {
public:
   int               x;
   double            y;
   CObject           *obj;
   void              CMyclass(void):x(-1),y(-2.2)  {                       }
   public: CMyclass *operator[] (CObject*p){ CMyclass*r = dynamic_cast<CMyclass*>(p); 
                                             return CheckPointer(r)!=POINTER_INVALID?r:NULL; }         
  };
//+------------------------------------------------------------------+
void OnStart()
  {
   CList *base=new CList;
   for(int i=0;i<3;i++)
     {
      base.Add(new CMyclass);
      ((CMyclass*)base.GetCurrentNode()).x = 99;
      ((CMyclass*)base.GetCurrentNode()).y = 555;
      CMyclass[base.GetCurrentNode()].x = 111;
     }

   for(int i=0;i<3;i++)
     {
      Print(((CMyclass*)base.GetNodeAtIndex(i)).x," : ",((CMyclass*)base.GetNodeAtIndex(i)).y);
     }
   delete base;
  }
//+------------------------------------------------------------------+

ЗЫ: немного начал понимать, что Вы предлагаете, но все равно результата нет, можно и без dynamic_cast <> обойтись, добавить поле * CObject , в теории вот так должно быть:

...
 CObject           *obj;
 CMyclass          *operator[](CObject*p)        { obj = p; return(obj); }          
  };

думаю так будет чуть быстрее работать, чем Ваш пример с dynamic_cast <> - смысл вроде один и тот же

 
Igor Makanu:

если возможность в MQL разыменовывать указатель *CObject ?

пробовал разные варианты, вот скрипт для теста, добавляю в связанный список 3 элемента Myclass и потом изменяю значения полей CMyclass, так все работает:

могу ли я изменять поля динамически созданных элементов CMyclass, без промежуточного указателя  CMyclass *result ?

примерно так: (CMyclass *)(base.GetCurrentNode()).x = 99;

PS: подозреваю, что нужно использовать typedef , но пока неудачно

То, что Вы написали просто неявное использование того же:

result=base.GetCurrentNode();

Т.е. такой анонимный указатель, а по сути просто синтаксический сахар. Сахара в MQL почти нет, поэтому так не получиться сделать. Но замечу приведение типа к потомку идет без всяких там проверок и преобразований потому очень быстро, из-за этого не совсем понятно, чем Вам так не угодила явная работа с указателем. 

 
Igor Makanu:

ЗЫ: немного начал понимать, что Вы предлагаете, но все равно результата нет, можно и без dynamic_cast <> обойтись, добавить поле * CObject , в теории вот так должно быть:

думаю так будет чуть быстрее работать, чем Ваш пример с dynamic_cast <> - смысл вроде один и тот же

Можно и без отдельного поля, как Вам предлагали выше делать, только через обертку в оператор. 

Разница есть, маленькая такая. Если там вдруг окажется не приводимый к myclass объект, то без dynamic_cast будет ошибка выполнения, а с ним - всего лишь NULL в возврате. Что при условии немедленного к нему обращение через .х в любом случае вызовет ошибку выполнения, так что можно и не париться =)))

Если совсем делать как "доктор прописал", то нужно в случае NULL возвращать что-то типа специального экземпляра класса, созданного для обработки этой ошибки )))

П.С. Я проверял скорость dynamic_casta недавно по сравнению с обычным приведением - была вроде в случае равенства класса ожидаемому почти такая же. 

П.С.С. В любом случае, for'ы там выглядят достаточно печально - при работе со списками нужно использовать циклы типа for each (вроде моего loop) 
 
Igor Makanu:

не пропускает компилятор:  '[' - name expected tst_cast.mq4 32 15

#property strict
#include <Object.mqh>
#include <Arrays\List.mqh>
//+------------------------------------------------------------------+
class CMyclass:public CObject
  {
public:
   int               x;
   double            y;
   CObject           *obj;
   void              CMyclass(void):x(-1),y(-2.2)  {                       }
   public: CMyclass *operator[] (CObject*p){ CMyclass*r = dynamic_cast<CMyclass*>(p); 
                                             return CheckPointer(r)!=POINTER_INVALID?r:NULL; }         
  };
//+------------------------------------------------------------------+
void OnStart()
  {
   CList *base=new CList;
   for(int i=0;i<3;i++)
     {
      base.Add(new CMyclass);
      ((CMyclass*)base.GetCurrentNode()).x = 99;
      ((CMyclass*)base.GetCurrentNode()).y = 555;
      CMyclass[base.GetCurrentNode()].x = 111;
     }

   for(int i=0;i<3;i++)
     {
      Print(((CMyclass*)base.GetNodeAtIndex(i)).x," : ",((CMyclass*)base.GetNodeAtIndex(i)).y);
     }
   delete base;
  }
//+------------------------------------------------------------------+

...

По факту-то что этой оберткой получили? Лишний dynamic_cast, когда он там совершенно не нужен? В самой обертке явное преобразование к тому же CMyClass. Т.е. рабочей нагрузки в ней 0%, а код более запутанный (оператор обращения по индексу используется в качестве оператора явного приведения передаваемого класса - ну вообще не очевидно).

 
Ilya Malev:
П.С.С. В любом случае, for'ы там выглядят достаточно печально - при работе со списками нужно использовать циклы типа for each (вроде моего loop) 

Извините, но это глупость же.

 
Vasiliy Sokolov:

То, что Вы написали просто неявное использование того же:

Т.е. такой анонимный указатель, а по сути просто синтаксический сахар. Сахара в MQL почти нет, поэтому так не получиться сделать. Но замечу приведение типа к потомку идет без всяких там проверок и преобразований потому очень быстро, из-за этого не совсем понятно, чем Вам так не угодила явная работа с указателем. 

да, я это все понимаю, никак не разберусь с синтаксисом в MQL  при работе с указателями, вроде все то же самое, что и в стандартном С++, но постоянно путаюсь и не могу ни с ходу написать чтонить, ни прочитать корректно код той же библиотеки из стандартной поставки  МТ.... все волосы уже себе повыдергивал! ... , но остались еще на .опе! )))) - все равно разберусь ;)


Ilya Malev:

Разница есть, маленькая такая. Если там вдруг окажется не приводимый к myclass объект, то без dynamic_cast будет ошибка выполнения, а с ним - всего лишь NULL в возврате. Что при условии немедленного к нему обращение через .х в любом случае вызовет ошибку

это все понятно, да и не маленькая это разница, скажу не кривя душой, что код профессионального программиста и отличается от любительского именно вот в этой разнице - в проверке критических ошибок .... хотя при современных тенденциях в языках программирования и это упростили для ламеров-програмеров c помощью try except finally и т.п.  ;)

 
Vasiliy Sokolov:

Извините, но это глупость же.

Да пожалуйста

 
Igor Makanu:

да, я это все понимаю, никак не разберусь с синтаксисом в MQL  при работе с указателями, вроде все то же самое, что и в стандартном С++, но постоянно путаюсь и не могу ни с ходу написать чтонить, ни прочитать корректно код той же библиотеки из стандартной поставки  МТ.... все волосы уже себе повыдергивал! ... , но остались еще на .опе! )))) - все равно разберусь ;)

С++ брать в качестве ориентира в случае с MQL не прокатит:) Объем того, что в MQL нельзя гораздо больше чем объем "совместимых" конструкций. Имхо, MQL больше похож на очень урезанный C# с полным отсутствием синтаксического сахара.

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