Fehler, Irrtümer, Fragen - Seite 2363

 
Igor Makanu:

typedef ist ein Thema, ich habe es versucht, aber es hat nicht geklappt, ich muss noch herausfinden, wo ich es vermasselt habe, mein Beispiel sollte auch mit typedef funktionieren!

Der Code, den ich oben geschrieben habe, sollte funktionieren. Ich wollte es selbst überprüfen, hatte aber kein Glück: =)))))))))))


(Baujahr 1961)

 
Igor Makanu:

typedef ist ein Thema, ich habe es versucht, aber es hat nicht geklappt, ich muss noch herausfinden, wo ich es vermasselt habe, mein Beispiel sollte auch mit typedef funktionieren!

Aber man kann es einfacher und eleganter machen - ohne unnötige Klammern und Zeiger - (und es kompiliert ohne seltsame Fehler))))

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

Können Sie es einfacher und eleganter machen - ohne unnötige Klammern und Zeiger - (und es kompiliert ohne seltsame Fehler))))

Ihr Beispiel wird in meinem Fall nicht funktionieren, meine Objekte werden dynamisch erstellt, ich weise ihnen nicht einmal einen Namen zu, während Ihr Beispiel einen Zeigernamen verwendet, ich habe es auf diese Weise versucht, der Compiler wird nicht durchlassen: '[' - Name erwartet 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: Ich habe begonnen, ein wenig zu verstehen, was Sie vorschlagen, aber immer noch kein Ergebnis, ich kann ohne dynamic_cast <> tun, fügen *CObject Feld, in der Theorie sollte es so sein:

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

Ich denke, es wird ein wenig schneller als Ihr Beispiel mit dynamic_cast <> funktionieren - die Bedeutung ist die gleiche

 
Igor Makanu:

ob es möglich ist, einen *CObject-Zeiger in MQL zu dereferenzieren?

Ich habe verschiedene Varianten ausprobiert, hier ist ein Skript zum Testen, ich füge 3 Myclass-Elemente zur verknüpften Liste hinzu und ändere dann die Werte der CMyclass-Felder, es funktioniert:

Kann ich Felder von dynamisch erstellten CMyclass-Elementen ändern, ohne den ZwischenzeigerCMyclass *result ?

Etwa so:(CMyclass *)(base.GetCurrentNode()).x = 99;

PS: Ich vermute, Sie müssen typedef verwenden, aber bisher erfolglos

Was Sie geschrieben haben, ist nur eine implizite Verwendung desselben:

result=base.GetCurrentNode();

D.h. ein solcher anonymer Zeiger, aber im Grunde nur syntaktischer Zucker. In MQL gibt es fast keinen Zucker, also kann man es so nicht machen. Aber ich sollte anmerken, dass Casting zu descendant ohne Prüfungen und Konvertierungen durchgeführt wird, so dass es nicht klar ist, warum Sie nicht wie explizite Arbeit mit einem Zeiger.

 
Igor Makanu:

ZS: ein wenig begann zu verstehen, was Sie vorschlagen, aber immer noch kein Ergebnis, können Sie ohne dynamic_cast <> tun, fügen Sie ein Feld * CObject , in der Theorie, sollte es so sein:

Ich denke, es wird ein wenig schneller als Ihr Beispiel mit dynamic_cast <> arbeiten - die Bedeutung ist die gleiche

Sie können dies auch ohne ein separates Feld tun, wie oben vorgeschlagen, aber nur durch einen Umbruch im Operator.

Es gibt einen kleinen Unterschied. Wenn plötzlich ein Objekt auftaucht, das nicht in myclass konvertiert wurde, gibt es ohne dynamic_cast einen Ausführungsfehler, und man erhält nur NULL zurück. Wenn Sie es sofort mit .x ansprechen, wird es ohnehin zu einem Laufzeitfehler führen, also lassen Sie es bleiben =)))

Wenn wir tun, was Arzt bestellt sollten wir so etwas wie spezielle Klasse Instanz für die Fehlerbehandlung )))) erstellt zurückgeben.

P.S. Ich habe kürzlich die Geschwindigkeit von dynamic_casta im Vergleich zum üblichen Casting überprüft - es war fast das gleiche im Falle der Gleichheit der Klasse mit der erwarteten.

P.S.S. Auf jeden Fall sehen for's dort ziemlich traurig aus - wenn Sie mit Listen arbeiten, sollten Sie Schleifen wie for each verwenden (wie meine Schleife)
 
Igor Makanu:

besteht nicht Compiler: '[' - Name erwartet 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;
  }
//+------------------------------------------------------------------+

...

Was haben wir eigentlich mit diesem Wrapper bekommen? Ein unnötiger dynamic_cast, wenn er absolut unnötig ist? Der Wrapper selbst hat eine explizite Umwandlung in CMyClass. D.h. er hat 0% Arbeitsaufwand, während der Code komplizierter ist (der Indexreferenzoperator wird als expliziter Konvertierungsoperator für die übergebene Klasse verwendet - nun, das ist überhaupt nicht offensichtlich).

 
Ilya Malev:
P.S.S. Auf jeden Fall sehen die for's dort ziemlich traurig aus - wenn Sie mit Listen arbeiten, sollten Sie Schleifen wie for each verwenden (wie meine Schleife)

Entschuldigung, aber das ist dumm.

 
Vasiliy Sokolov:

Was Sie geschrieben haben, ist nur eine implizite Verwendung desselben:

D.h. ein solcher anonymer Zeiger, aber im Grunde nur syntaktischer Zucker. In MQL gibt es fast keinen Zucker, also kann man es nicht auf diese Weise machen. Aber ich sollte darauf hinweisen, dass Casting zu descendant geht ohne Prüfungen und Konvertierungen, so ist es nicht klar, warum explizite Arbeit mit dem Zeiger so lästig ist.

Ja, ich verstehe es, ich bin immer noch mit der Syntax in MQL verwirrt, wenn ich mit Zeigern arbeite, es scheint das gleiche wie in Standard-C++, aber ich bin ständig verwirrt und kann weder etwas sofort schreiben, noch den Code der Bibliothek aus dem Standardpaket MT.... richtig lesen Ich habe mir alle Haare ausgerissen! ... aber immer noch auf der .opera! )))) - Ich werde es trotzdem herausfinden ;)


Ilya Malev:

Es gibt einen Unterschied, einen kleinen Unterschied. Wenn es zufällig ein Objekt gibt, das nicht in myclass konvertiert wurde, gibt es ohne dynamic_cast einen Ausführungsfehler, und mit dynamic_cast erhält man einfach NULL zurück. Das führt auf jeden Fall zu einem Fehler, wenn Sie es sofort mit .x ansprechen.

Ich verstehe all dies, und es ist kein kleiner Unterschied, ich werde aufrichtig sagen, dass sich der Code eines professionellen Programmierers von dem eines Amateurs durch genau diesen Unterschied unterscheidet - bei der Überprüfung kritischer Fehler ..... obwohl mit den modernen Trends in den Programmiersprachen wurde es für lahmere Programmierer mit try außer finally usw. vereinfacht ;)

 
Vasiliy Sokolov:

Es tut mir leid, aber das ist albern.

Oh, bitte.

 
Igor Makanu:

Ja, ich verstehe alles, ich kann nicht herausfinden, die Syntax in MQL bei der Arbeit mit Zeigern, es scheint das gleiche wie in Standard-C++, aber ich bin ständig verwirrt und kann weder etwas sofort zu schreiben, noch richtig den Code der gleichen Bibliothek aus der Standard-MT.... Lieferung lesen Ich habe mir alle Haare ausgerissen! ... aber immer noch auf der .opera! )))) - Finde es heraus ;)

C++ als Bezugspunkt im Falle von MQL zu nehmen, wird nicht funktionieren :) Die Menge dessen, was in MQL unmöglich ist, ist viel größer als die Menge der "kompatiblen" Konstrukte. Imho ist MQL eher wie ein sehr verkürztes C# mit einem vollständigen Mangel an syntaktischem Zucker.