Hilfe bei OOP - Seite 3

 
Vasiliy Sokolov #:

GUT. Das verstehe ich nicht. Verstehen Sie das? Sind Sie sicher, dass Sie das verstehen? Was genau?

Das Argument läuft auf die folgende Aussage hinaus:

...

Dabei ging es nicht um einen allgemeinen Streit, sondern um eine Situation, die einen einzelnen Beitrag betraf, und ich habe erklärt, worin das Problem bestand. Okay, es gab keine Katastrophe.

 

Deklariertes Array double x[268435448];

Das gleiche Array in der Funktion OnStart().

Außerdem wurde ein rekursiver Aufruf mit LONG_MAX Tiefe durchgeführt.

Keine Probleme.

 
fxsaber #:

Verwenden Sie keine statischen Arrays?

groß. Wenn die Größe des Feldes klein, konstant und im Voraus bekannt ist, ist statisch besser und wahrscheinlich schneller.

 
Andrei Trukhanovich #:

groß. Wenn die Größe des Feldes klein, konstant und im Voraus bekannt ist, ist statisch besser und wahrscheinlich schneller.

Ich würde gerne eine Möglichkeit haben, eine Liste von statischen Variablen/Arrays und deren Größen zu erhalten. Wahrscheinlich braucht man einen Code-Parser wie hier.

Ich schätze, ein statisches String-Array und ein Double-Array sind ganz unterschiedliche Dinge.

MQL5 Program Packer
MQL5 Program Packer
  • www.mql5.com
This is MQL5 project packer: assemble all source and resource files from dependencies into a single ZIP.
 
fxsaber #:

Ich schätze, dass statische String-Arrays und Double-Arrays ganz unterschiedliche Dinge sind.

string ist im Wesentlichen eine interne Klasse, die aus einem Zeiger und int size besteht, d.h. für double array wird bedingt 1,5 mal weniger Platz benötigt

Ich glaube nicht, dass es viel Sinn macht, sich damit zu beschäftigen, es sei denn, Sie haben statische Arrays mit Millionen von Elementen.

 
fxsaber #:

Keine statischen Arrays verwenden?

Es gibt also im Wesentlichen vier Arten von Daten in MQL:

  • Statische, vordefinierte Daten. Wird zur Kompilierzeit in das Programm eingefügt und nicht mehr geändert. Sie befinden sich in einem privaten Speicherbereich. Dies sind zum Beispiel statische Arrays vom Typ char[1024].
  • Manuell verwaltete Daten über die Zeiger. Dies sind Instanzen von Klassen, die jedoch durch Zeiger definiert sind, z. B. CFoo* bar, wobei bar eine Instanz von CFoo ist. Diese Instanzen sind vom Typ POINTER_DYNAMIC. Dieser Speichertyp ist der problematischste, obwohl er in den meisten Fällen nicht erforderlich ist.
  • Daten, die vom Müllsammler der virtuellen Maschine mql verwaltet werden, auf der das Programm ausgeführt wird. Dazu gehören auch Instanzen von Klassen. Der Zeiger auf ein Objekt dieses Typs ist POINTER_AUTOMATIC. Diese Objekte selbst befinden sich entweder im Heap dieser virtuellen Maschine oder im privaten Bereich. Wie genau, hängt offenbar von den Daten und ihrem Umfang ab und davon, was die Entwickler haben. Diese Information ist nicht verfügbar. Zu diesen Daten gehören zum Beispiel Benutzerklassen. Jede Definition einer Klasseninstanz ohne Zeiger definiert diesen Speichertyp. Zum Beispiel definiert CFoo bar eine Instanz der bar-Klasse CFoo, deren Zeiger nicht freigegeben werden muss. Die virtuelle Maschine führt alle Vorgänge der Freigabe aus. Sie brauchen den Löschoperator nicht zu verwenden und stehen daher vor dem Problem der durchgesickerten Objekte.
  • Die Daten befinden sich auf dem Stapel. Dies sind in erster Linie lokale Variablen von Funktionen. Wenn wir z.B. int a = 5 in eine beliebige Funktion schreiben, wird das obere Ende des Stacks um 4 Bytes nach oben verschoben, wodurch die benötigte Speichergröße zugewiesen wird. Vielleicht sind in MQL die auf dem Stack gespeicherten Typen auch Strukturen (ich habe das nie überprüft, um ehrlich zu sein). Solche Daten nehmen nicht viel Platz ein, und selbst wenn man eine Kette von Aufrufen verschachtelter Funktionen berücksichtigt, benötigt der Stack als Ganzes viel weniger Speicher als ein Heap. Diese Art der Speicherung wird automatisch verwendet, Sie müssen nicht darüber nachdenken.

Wenn wir den Stack den Funktionen und ihren lokalen Variablen überlassen, haben wir nur noch drei Typen, mit denen wir arbeiten können. Ich persönlich bin der Meinung (und das ist nur meine Meinung), dass Daten, die mit automatischer Lebensdauer definiert werden, die Vorteile der beiden vorgenannten Arten gut vereinen, ohne deren Nachteile. Daten, die mit automatischen Zeigern definiert werden, sind ebenso vorhersehbar und sicher wie statische, aber ebenso flexibel wie dynamische, manuell gesteuerte Daten. Mit Vorhersehbarkeit meine ich Szenarien, in denen es nicht notwendig ist, zusätzliche Überprüfungen der Zeigerbits vorzunehmen und sich zu fragen, ob jemand anderes die Daten bereits vorher gelöscht hat. Mit Flexibilität meine ich Szenarien, in denen man mit Daten, auf die ein Auto-Zeiger verweist, wie mit einem normalen Zeiger arbeiten kann, indem man den Zeiger an eine Funktion übergibt oder, bei Arrays, indem man ihn wiederverwertet.

Um zu veranschaulichen, was ich gerade gesagt habe, können Sie den ursprünglichen Code von Ihor Herasko und den gleichen Code, den ich für POINTER_AUTOMATIC geschrieben habe, vergleichen. Es gibt keine zusätzlichen Prüfungen und Initialisierungen, kein 60 000 000-maliges Löschen durch einen Operator. All dies spart Ihnen Zeit, Mühe und - was auch wichtig ist - Ressourcen. Wenn man sie versteht, braucht man fast nie mit Zeigern zu arbeiten. Sie können jederzeit einen solchen Algorithmus schreiben, der diese Arbeit entweder minimiert oder gar nicht erst anfängt. Zum Beispiel behandle ich Objekte in meinem Code nie manuell - das ist einfach nicht nötig. Was statische Arrays angeht, so muss ich sie manchmal verwenden, um zum Beispiel die benötigten Daten in das Programm einzubauen, aber das sind so spezielle Dinge, dass normale Benutzer sie nicht brauchen, nehme ich an. Am besten ist es, fertige Sammlungen wie CArrayObj oder eigene zu verwenden. Mit Templates und MQL-Funktionen können Sie nun sehr flexible Dinge erstellen, die viel besser sind als statische Arrays.

 
Im emcool gibt es keinen Mülleimer.
 

Vasiliy Sokolov #:

Statische, vordefinierte Daten. Zur Kompilierzeit in das Programm eingefügt und nicht mehr geändert. Sie werden in einem privaten Speicherbereich gespeichert. Dies sind zum Beispiel statische Arrays vom Typ char[1024].

Wenn das Array nicht initialisiert ist,

int A[] = {1, 2}; // Инициализация
int B[2];         // Без инициализации

warum sollte sie in EX5 aufgenommen werden?

 
fxsaber #:

Wenn das Array nicht initialisiert ist,

warum sollte es in EX5 eingefügt werden?

Ja, das stimmt, die nicht initialisierten sind natürlich nicht eingenäht. Die initialisierten schon. Die Größen der beiden Typen werden jedoch zum Zeitpunkt der Kompilierung festgelegt und ändern sich nicht mehr. Das heißt, statische Arrays können bedingt in zwei Gruppen unterteilt werden.

 
Dmitry Fedoseev #:
In emcool gibt es keinen Müllsammler.

Offiziell, ja. Inoffiziell deutet vieles darauf hin, dass es sie gibt:

  • In MQL gibt es keine Zeiger. Stattdessen werden sie durch etwas ersetzt, das ihnen sehr ähnlich sieht.
  • In MQL gibt es keine direkte Speicherzuweisung, wie z.B. in C;
  • Programme in MQL werden von einer bestimmten virtuellen Maschine ausgeführt. Renat hat darüber nur kurz und nicht ein einziges Mal geschrieben;
  • Es kann eine Klasseninstanz definiert werden, die automatisch freigegeben wird. Es gibt also einen Mechanismus, der diese Instanzen überwacht und sie bei Bedarf freigibt. Was ist das, wenn nicht ein Müllsammler?
  • Alle Instanzen, die durch einen Zeiger initialisiert und nicht ordnungsgemäß freigegeben werden, werden beim Beenden als durchgesickerte Objekte markiert. Ihre Anzahl und die Gesamtgröße des verlorenen Speichers werden ausgedruckt. Ein Programm mit ausgelaufenem Speicher wird nicht einmal in Market validiert. Damit sind alle Objekte, auch die manuell zugewiesenen, erfasst, bekannt und dem System bekannt. Dies ist eine der klassischen Aufgaben, die die Müllabfuhr löst.