Errors, bugs, questions - page 2363

 
Igor Makanu:

typedef is a topic, I tried it, but it didn't go well, I still need to figure out where I messed up, my example should work with typedef too!

The code I wrote above should work. I wanted to check it myself, but no luck: =)))))))))))


(build 1961)

 
Igor Makanu:

typedef is a topic, I tried it, but it didn't go well, I still need to figure out where I messed up, my example should work with typedef too!

But you can make it simpler and more elegant - without unnecessary brackets and pointers - (and it compiles without strange errors))))

#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:

Can you make it simpler and more elegant - without unnecessary brackets and pointers - (and it compiles without strange errors))))

your example won't work in my case, my objects are dynamically created, I don't even assign them a name, while your example uses a pointer name, I tried it this way, the compiler won't let through: '[' - 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;
  }
//+------------------------------------------------------------------+

SZZ: I've started to understand a little bit what you suggest, but still no result, I can do without dynamic_cast <>, add *CObject field, in theory it should be like this:

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

I think it will work a bit faster than your example with dynamic_cast <> - the meaning is the same

 
Igor Makanu:

if it's possible to dereference a *CObject pointer in MQL ?

I tried different variants, here is a script for test, I add 3 Myclass elements to linked list and then change values of CMyclass fields, it works:

Can I modify fields of dynamically created CMyclass elements, without intermediate pointerCMyclass *result ?

Like this:(CMyclass *)(base.GetCurrentNode()).x = 99;

PS: I suspect you need to use typedef , but so far unsuccessful

What you wrote is just an implicit use of the same:

result=base.GetCurrentNode();

I.e. such an anonymous pointer, but essentially just syntactic sugar. There's almost no sugar in MQL, so it can't be done that way. But I should note that casting to descendant is done without any checks and conversions, so it's not clear why you don't like working with an explicit pointer.

 
Igor Makanu:

ZS: a little bit started to understand what you suggest, but still no result, you can do without dynamic_cast <>, add a field * CObject , in theory, it should be like this:

I think it will work a little faster than your example with dynamic_cast <> - the meaning is the same

You can do it without a separate field, as suggested above, but only through wrapping in the operator.

There is a small difference. If suddenly there appears an object not converted to myclass, then without dynamic_cast there will be an execution error, and with it, you will get NULL in return. If you address it with .x immediately, it will cause execution error anyway, so you don't need to worry about it =)))

If we do what doctor ordered we should return something like special class instance created for error handling ))))

P.S. I've checked speed of dynamic_casta recently, compared to usual casting - it was almost the same in case of equality of class to expected one.

P.S.S. In any case, for's look rather sad there - when working with lists, you should use loops like for each (like my loop)
 
Igor Makanu:

does not pass compiler: '[' - 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;
  }
//+------------------------------------------------------------------+

...

What did we actually get with this wrapper? An unnecessary dynamic_cast when it is absolutely unnecessary? The wrapper itself has an explicit conversion to CMyClass. I.e. it has 0% workload while the code is more complicated (the index reference operator is used as an explicit conversion operator for the class being passed - well, it's not obvious at all).

 
Ilya Malev:
P.S.S. In any case, the for's look rather sad there - when working with lists, you should use loops like for each (like my loop)

Sorry, but that's silly.

 
Vasiliy Sokolov:

What you wrote is just an implicit use of the same:

I.e. such an anonymous pointer, but basically just syntactic sugar. There is almost no sugar in MQL, so you can't do it that way. But I should point out that casting to descendant goes on without any checks and conversions, so it's not clear why explicit work with the pointer is so annoying.

Yes, I understand it, I'm still confused with syntax in MQL when working with pointers, it seems the same as in standard C++, but I'm constantly confused and can neither write something straight away, nor read the code of the library from the standard MT.... package correctly I pulled all my hair out! ... but still on the .opera! )))) - I'll figure it out anyway ;)


Ilya Malev:

There is a difference, a small one. If there happens to be an object not converted to myclass, without dynamic_cast there will be an execution error, and with it you will get just NULL in return. Which will anyway cause an error if you address it with .x immediately.

I understand all this, and it is not a small difference, I will say sincerely that the code of a professional programmer differs from an amateur one in this very difference - in checking critical errors ..... although with modern trends in programming languages it has been simplified for lamer programmers using try except finally etc. ;)

 
Vasiliy Sokolov:

I'm sorry, but this is silly.

Oh, please.

 
Igor Makanu:

Yes, I understand it all, I can't figure out the syntax in MQL when working with pointers, it seems to be the same as in standard C++, but I am constantly confused and can neither write something straight away, nor read correctly the code of the same library from the standard MT.... delivery I pulled all my hair out! ... but still on the .opera! )))) - figure it out ;)

Taking C++ as a reference point in case of MQL will not work :) The volume of what's impossible in MQL is much larger than the volume of "compatible" constructs. Imho, MQL is more like a very truncated C# with a complete lack of syntactic sugar.

Reason: