Merkmale der Sprache mql5, Feinheiten und Techniken - Seite 110

 

Forum zum Thema Handel, automatisierte Handelssysteme und Testen von Handelsstrategien

Wanzen, Wanzen, Fragen

fxsaber, 2018.12.01 11:15

Super-Bremse Design
string Str[];
const int handle = FileOpen(FileName, FILE_READ | FILE_ANSI | FILE_TXT);  

FileReadArray(handle, Str);

Das Lesen einer 40-MB-Datei mit 1 Million Zeilen dauert 18 Sekunden.


Das gleiche Ergebnis, aber anders gemacht

  uchar Bytes[];
  const int handle = FileOpen(FileName, FILE_READ | FILE_BIN);
  
  FileReadArray(handle, Bytes);

  string Str[];
  StringSplit(CharArrayToString(Bytes), '\n', Str);

Ist bereits in 0,5 Sekunden erledigt.


 
Ein künstlicher Trick zum Kompilieren
#define  MACROS(A, B) A / B + !(A / B) // (A >= B) ? A / B : 1

template <typename T1, typename T2>
union UNION
{
  T1 a;
//  T2 b[sizeof(T1) / sizeof(T2)];      // '[' - invalid index value
  T2 b[MACROS(sizeof(T1), sizeof(T2))]; // OK
};

template <typename T1, typename T2>
void f()
{
  if (sizeof(T1) >= sizeof(T2))
    UNION<T1, T2> Union;
  else
    UNION<T2, T1> Union;  
}

void OnStart()
{
  f<int, char>();
}
 

Ein einfaches Gegenstück zu auto_ptr (gilt als veraltet). Anmerkung: nicht ganz analog, mit
...


https://habr.com/post/140222/

Smart pointers для начинающих
Smart pointers для начинающих
  • habr.com
Эта небольшая статья в первую очередь предназначена для начинающих C++ программистов, которые либо слышали об умных указателях, но боялись их применять, либо они устали следить за new-delete. UPD: Статья писалась, когда C++11 еще не был так популярен. Итак, программисты С++ знают, что память нужно освобождать. Желательно всегда. И они знают...
 

pavlick_

Bei operator= müssen Sie am Anfang eine Zeile hinzufügen:

if (p==other.p) return &this;
 

Aber es lohnt sich wahrscheinlich, sich auf so etwas zu beschränken (man kann überhaupt nicht kopieren):

template <typename T_>
class unique_ptr{
   T_ *p;
public:
   unique_ptr(void *ptr=NULL): p(ptr)           {}
   ~unique_ptr()                                {reset();}
   unique_ptr *operator=(T_ *p_)                {reset(); p = p_; return &this;}
   // releases ownership of the managed object
   T_ *release()                                   {T_ *r = p; p = NULL; return r;}
   // destroys the managed object 
   void reset()                                    {if(p) delete p; p=NULL;}
   // returns a pointer to the managed object 
   T_ *get()                                       {return p;}
   unique_ptr(const unique_ptr<T_> &other);
   void operator=(const unique_ptr<T_> &other);
   void swap(unique_ptr<T_> &other){
      T_ *buf = p;
      p = other.p;
      other.p = buf;
   }
};
Warum habe ich das Kopieren für auto_ptr? Wegen der Krümmung von µl - um ein Stack-Objekt in CArrayObj zu kopieren, müssen Sie eine Reihe von Objekten erstellen, indem Sie den Konstruktor mehrmals aufrufen. Aber ich glaube nicht, dass es das wert ist. In diesem Zusammenhang werde ich den ersten Beitrag löschen.
 
pavlick_:

Warum habe ich das Kopieren für auto_ptr? Wegen der μl-Krümmung - um ein Stack-Objekt in CArrayObj zu kopieren, müssen Sie eine Reihe von Objekten erstellen, indem Sie den Konstruktor mehrmals aufrufen.

Und warum "die Krümmung von μl"?

 
Alexey Navoykov:

Und warum die "Krümmung des µl"?

Die triviale Aufgabe, eine Kopie eines Stack-Objekts zu einem Array hinzuzufügen, besteht darin, einen Standardkonstruktor hinzuzufügen, den ich von vornherein nicht brauchte:

class Q : public CObject {
public:
   Q() {}
   Q(int i) {}
};

void OnStart()
{
   CArrayObj ar;
   Q q(3);
   
   Q *new_el = new Q;
   new_el = q;
   ar.Add(new_el);
   Q new_el2(5);
   q = new_el2;
}

Es ist nicht fatal, ja, Sie können init() in Q ausführen, was das Problem ein wenig glättet, aber es ist trotzdem ekelhaft. Und beim Kopieren von auto_ptr auf der Hand, alles geschieht in zwei Zeilen, aber das Spiel ist nicht wert die Mühe. Vielleicht zu wählerisch, Perfektionismus.

 
pavlick_:

Die triviale Aufgabe, eine Kopie eines Stack-Objekts zu einem Array hinzuzufügen, entpuppt sich als Folgendes: Ich muss einen Standardkonstruktor vorschreiben, den ich gar nicht brauche:

Es ist nicht fatal, ja, Sie können init() bei Q ausführen, was das Problem etwas glättet, aber es ist immer noch ekelhaft. Und beim Kopieren von auto_ptr auf der Hand, alles geschieht in zwei Zeilen, aber das Spiel ist nicht wert die Mühe. Vielleicht zu wählerisch, Perfektionismus.

Aber es ist genau das gleiche in C++ auch, so ist es nicht wirklich klar, warum die krumme mcl.

Und in Ihrem Fall ist es einfacher, einen Kopierkonstruktor anzugeben und Elemente mit einer Zeile hinzuzufügen:

ar.Add(new Q(q));
 
pavlick_:

Die triviale Aufgabe, eine Kopie eines Stack-Objekts zu einem Array hinzuzufügen, entpuppt sich als Folgendes: Ich muss einen Standardkonstruktor schreiben, den ich überhaupt nicht benötige:

Es ist nicht fatal, ja, Sie können init() bei Q ausführen, was das Problem ein wenig glättet, aber es ist immer noch ekelhaft. Und wenn man auto_ptr kopiert, passiert alles in zwei Zeilen, aber das Spiel ist die Mühe nicht wert. Vielleicht zu wählerisch, Perfektionismus.

Das ist, wie es alle sowieso passiert - es ist nur hinter Ihrem auto_ptr versteckt...

Ich sehe hier keine besonderen Probleme.

Als abgehärteter Oldtimer mag ich den C#-Ansatz, bei dem der Speicher automatisch gelöscht wird, wirklich nicht. Meiner Meinung nach sollte die Person, die die Löschung von Objekten beantragt hat, dafür verantwortlich sein und nicht irgendwelche "Müllsammler".

 
Alexey Navoykov:

Aber in C++ ist es genau dasselbe, so dass es nicht ganz klar ist, warum der mcl schief ist.

Und in Ihrem Fall ist es einfacher, einen Kopierkonstruktor anzugeben und Elemente in einer Zeile hinzuzufügen:

Warum ist es dasselbe? Dort gibt es automatisch einen Kopierkonstruktor und alle Manipulationen werden nachgeschaut:

class Q : public CObject {
public:
   Q(int i) {}
};

void OnStart()
{
   CArrayObj ar;
   Q q(3);
   
   ar.Add(new(q));
   q = Q(5);
}

Und in Ihrem Fall ist es einfacher, den Kopierkonstruktor zu setzen und Elemente mit einer Zeile hinzuzufügen

Natürlich ist es zum Beispiel eine Spielzeugklasse, in Wirklichkeit sind es auch einige Daten, wahrscheinlich eine Menge, es ist keine Option, überhaupt einen Kopierkonstruktor zu schreiben. An den richtigen Stellen in Wrapper eingewickelt und keine Notwendigkeit für einen benutzerdefinierten Konstruktor.

Es geschieht also alles trotzdem - es ist nur hinter Ihrem auto_ptr versteckt...

Ich sehe hier kein besonderes Problem.

Als abgehärteter Oldtimer mag ich den C#-Ansatz nicht, bei dem der Speicher automatisch gelöscht wird. Meiner Meinung nach sollte die Person, die die Löschung von Objekten beantragt hat, dafür verantwortlich sein, und nicht irgendein Müllsammler.

In µl können Sie auf intelligente Zeiger verzichten. Müllsammler != intelligente Zeiger, auf die man zumindest wegen der Ausnahmen nicht verzichten kann. Ich selbst mag keine Müllsammler.