Fragen zu OOP in MQL5 - Seite 9

 
Igor Makanu:

Über welche Tonnen reden wir? alles, was übersehen wurde, wird vom Terminal gemeldet, die Stelle, an der es zu löschen ist, ist auch bekannt - OnDeint() .... Ist diese Diskussion zu einer Diskussion über ein kugelförmiges Pferd in einem Vakuum geworden? )))

Nein. Lassen Sie das Pferd reiten, wo es soll.

Aber wir sprechen hier über die Schaffung von bisher unbekannten Objekten. Und wir kennen nicht nur ihre Eigenschaften, sondern auch die Anzahl der erstellten Objekte selbst nicht.

Natürlich können wir für ein Objekt einen Zeiger erstellen und mit diesem Objekt über diesen Zeiger arbeiten. Aber was ist das für ein Vakuum, wenn wir nicht im Voraus wissen, wie viele Zeiger wir brauchen werden? Es ist nur eine der einfachsten und sofort verfügbaren - Zeiger in Listen zu speichern. Sie können der Liste entnommen werden. Nun, jedes Objekt kann einen eigenen Bezeichner haben (die Methode Type()), mit dem Sie das Zeigerobjekt identifizieren können. Es ist möglich, ein Objekt genau zu identifizieren (zusätzlich zu seinem Typ kann ein Objekt mit anderen Eigenschaften ausgestattet sein, die es von den Objekten desselben Typs unterscheiden).

Im Allgemeinen habe ich das Gefühl, dass ich über komplexere Strukturen spreche, die eine Klassifizierung von Objekten, Listen für ihre Speicherung und Methoden für die Arbeit mit Objekten erfordern, die nicht nur Informationen speichern und auf Anfrage weitergeben können, sondern auch "leben und wachsen", indem sie mit dem Programm interagieren, sich von Zeit zu Zeit selbst verändern und über ihre Aktionen berichten.

Vielleicht bin ich zu weit gegangen und diskutiere nur ein Objekt, bei dem zwei Felder während der Initialisierung geändert werden müssen und sich während der Lebensdauer des Objekts in keiner Weise ändern dürfen. Was nützt ein Objekt, wenn es Eingabevariablen gibt?

 
Niemand ist verpflichtet, einen Gegenstand zu entfernen, außer derjenige, der ihn geschaffen hat. Selbst wenn dies in einigen Fällen der Fall ist, sollte man sich nicht darauf verlassen. Wenn Sie es erstellt haben, löschen Sie es.
 
Dmitry Fedoseev:
Niemand ist verpflichtet, ein Objekt zu löschen, außer derjenige, der es erstellt hat. Auch wenn dies in einigen Fällen der Fall ist, sollte man sich nicht darauf verlassen. Wenn Sie es erstellt haben, löschen Sie es.

Das ist wahr. Aber das ist nicht das, worüber wir hier sprechen. Nicht wahr?

Es geht um Methoden, mit denen Objekte definitiv nicht verloren gehen, sondern eindeutig wiedergefunden werden können.

Wenn Sie ein Objekt erstellen, sollten Sie sich dessen bewusst sein und es nicht verlieren, damit es später ordnungsgemäß gelöscht wird und es kein Speicherleck aufgrund eines verlorenen Objektzeigers gibt (wir haben mit dem Speicherleck im Beispiel begonnen, bei dem der Zeiger auf das an die Funktion übergebene Objekt dem neu erstellten Objekt im Funktionskörper neu zugewiesen wurde).

Und jeder hat seine eigenen Vorlieben - manche mögen das eine, manche das andere. Aber wir müssen über jedes unserer Objekte Bescheid wissen - auch wenn es zwei oder zweitausendundzwei davon gibt -, damit wir sie später löschen können. Und ob wir sie selbst mit delete löschen oder mit Clear() von list löschen lassen oder in einer Schleife mit list und delete oder auf andere Weise - darum geht es nicht.

 
Artyom Trishkin:

Im Allgemeinen denke ich, dass ich über komplexere Strukturen spreche, die eine Klassifizierung von Objekten, Listen für ihre Speicherung und Methoden für die Arbeit mit Objekten erfordern, die nicht nur Informationen speichern und auf Anfrage weitergeben können, sondern auch "leben und sich entwickeln", indem sie mit dem Programm interagieren, sich von Zeit zu Zeit verändern und über ihre Aktionen berichten.

Vielleicht bin ich zu weit gegangen und wir müssen nur über ein Objekt diskutieren, bei dem zwei Felder bei der Initialisierung geändert werden müssen und sich während der Lebensdauer in keiner Weise ändern dürfen? Was nützt ein Objekt, wenn es Eingabevariablen gibt?

Das ist ein merkwürdiges Konzept von OOP: Zunächst einmal ist OOP bequem - man schreibt es einmal und erstellt dann neue Instanzen des Objekts.

Um auf den Anfang der Diskussion zurückzukommen, hier mein Beispiel, das ich oft verwende: https://www.mql5.com/ru/forum/160683/page861#comment_11840254

Ich muss meinen Handel jetzt auf ein Zeitintervall beschränken und beim nächsten Mal auf zwei... 4...

mein 2-Klick-Beispiel wird für diese Aufgabe modifiziert:

int OnInit()
{
   Work1=new CWorkTime(StartHour1,StartMinute1,StopHour1,StopMinute1);
   Work2=new CWorkTime(StartHour2,StartMinute2,StopHour2,StopMinute2);
   Work3=new CWorkTime(StartHour3,StartMinute3,StopHour3,StopMinute3);
   Work4=new CWorkTime(StartHour4,StartMinute4,StopHour4,StopMinute4);
}


Ich weiß nicht, aber wenn man in Kategorien denkt, dass OOP nur dazu da ist, alles in eine Klasse zu packen, dann ist es ein Wunder - meine Superklasse und sie kann beides... Und wenn die Klasse aus 10 Strings besteht, brauchen Sie kein OOP - warum sollten Sie sich einschränken und alle in die Irre führen?

Ich benutze OOP, wo es für mich bequem ist, die Diskussion ist eindeutig zur Religion geworden - zu verbieten oder OOP zu benutzen ))))

 
Igor Makanu:

Das ist eine seltsame Vorstellung von OOP, denn OOP ist in erster Linie bequem - einmal schreiben, dann neue Instanzen des Objekts erstellen

Um auf den Anfang der Diskussion zurückzukommen, hier mein Beispiel, das ich oft verwende: https://www.mql5.com/ru/forum/160683/page861#comment_11840254

Ich muss meinen Handel jetzt auf ein Zeitintervall beschränken und beim nächsten Mal auf zwei... 4...

mein 2-Klick-Beispiel wird für diese Aufgabe modifiziert:


Ich weiß nicht, aber wenn man in Kategorien denkt, dass OOP nur dazu da ist, alles in eine Klasse zu packen, dann ist es ein Wunder - meine Superklasse und sie kann beides... Und wenn die Klasse aus 10 Strings besteht, brauchen Sie kein OOP - warum sollten Sie sich einschränken und alle in die Irre führen?

Dort, wo es für mich bequem ist, verwende ich OOP, die Diskussion ist eindeutig auf die Religion übergegangen - zu verbieten oder OOP zu verwenden ))))

Auf jeden Fall - ich bin nicht derjenige, der in diese Religion geht, da ich selbst aktiv OOP verwende.

Zum Beispiel: Was, wenn wir mehr Intervalle brauchen? Sollten wir neue schaffen? Und wozu? Wenn Sie mit einer Liste auskommen können, ohne den Programmcode zu beeinträchtigen.

Wir scheinen über unterschiedliche Dinge zu sprechen. Ich spreche von Benutzerfreundlichkeit, und Sie... Ich spreche auch von Benutzerfreundlichkeit, aber Sie zeigen Code, der nicht brauchbar ist. Vielleicht war es auch nur übertrieben, und ich habe es nicht verstanden...

 
Artyom Trishkin:

Zum Beispiel: Was ist, wenn mehr Intervalle benötigt werden? Sollten neue WorkNNNs geschaffen werden? Was soll das bringen? Wenn Sie mit einer Liste auskommen, ohne in den Programmcode einzugreifen...

Wenn wir Listen oder Arrays von Klasseninstanzen verwenden müssen, ist das keine große Sache, aber es ist einfacher, ein Array für dieses Beispiel zu verwenden und nur eine Schleife zu machen:

bool DisableTrade=false;
   for(int i=0;i<ArraySize(Work);i++)
     {
      if(Work[i].Disable()) {DisableTrade=true; break}
     }
   if(DisableTrade)
     {
      Comment("Не торговое время!!! Сопровождение открытых ордеров");
     }
   else...

Artyom Trishkin:

Wir scheinen über unterschiedliche Dinge zu sprechen. Ich spreche von Benutzerfreundlichkeit, und Sie ... Ich spreche auch von Benutzerfreundlichkeit, aber der Code, den Sie zeigen, ist nicht praktisch. Vielleicht ist es natürlich nur übertrieben und ich habe es nicht verstanden...

Leider ist es unmöglich, universellen Code zu schreiben. Selbst wenn Sie universellen Code schreiben, wird seine weitere Modifizierung ein langwieriger Prozess sein, und als Folge davon wird universeller Code ressourcenintensiver sein - im Allgemeinen kann man ewig darüber reden, ich habe einmal geschrieben, dass einer der berühmten Programmierer sagte -"der Code muss seine Aufgabe erfüllen! - das ist genug". Der ganze Rest ist ... Nun, es ist der Wunsch, herumzualbern oder... sagen wir, zu schaffen! )))

 
Artyom Trishkin:

///

Zum Beispiel: Was ist, wenn mehr Intervalle benötigt werden? Sollten neue WorkNNNs geschaffen werden? Was soll das bringen? Wenn Sie mit einer Liste auskommen können, ohne den Programmcode zu beeinträchtigen.

///

Dann gibt es keine numerischen Intervallparameter im Eigenschaftsfenster. Sie werden nicht in der Lage sein, sie zu optimieren. Kommt nicht in Frage.

Auch die Erstellung eines neuen Objekts für jedes Intervall ist nicht die beste Lösung. Dennoch wird dies zu einer langsameren Leistung führen. Wenn wir eine Klasse erstellen würden, sollten wir eine erstellen, die die Parameter von Intervallen in ein Array einfügt. Es wird schneller gehen.

 
Dmitry Fedoseev: rmosa. Wenn Sie eine Klasse erstellen müssen, sollte diese so beschaffen sein, dass sie Parameter von Intervallen in ein Array einfügt. Es wird schneller gehen.

Es macht keinen Unterschied, ob Sie eine Klasse oder eine Funktion erstellen, der Sie mehrere Parameter hinzufügen(), oder ob Sie mehrere Klassen mit individuellen Parametern erstellen

SZZ: Vergessen Sie nicht, dass, wenn Sie eine große Funktion in Form eines langen "Pferdebandes" schreiben - der CPU-Cache wird nicht immer effektiv genutzt werden, obwohl es einen Gewinn in einem solchen "Pferdeband" bei der Vorhersage von Übergängen geben kann.... Das können nur Tests zeigen, aber auf einem bestimmten PC und mit einem bestimmten Compiler...

 
Dmitry Fedoseev:

Dann gibt es keine numerischen Intervallparameter im Eigenschaftsfenster. Sie werden nicht in der Lage sein, sie zu optimieren. Kommt nicht in Frage.

Die Erstellung eines neuen Objekts für jedes Intervall ist auch nicht die beste Option. Dies führt nämlich zu einer geringeren Leistung. Wenn wir eine Klasse erstellen würden, sollten wir eine erstellen, die die Parameter von Intervallen in ein Array einfügt. Es würde schneller gehen.

Einverstanden. Auch hier kommt es auf die Methoden zur Einstellung der Kassenfelder an. Und wie man sie von den Eingabeparametern auf das Objekt überträgt, das alle Intervalle speichert, ist eine Frage der Technik. Obwohl es möglich ist, alle Objekte in der Liste der Intervalle neu zu erstellen, und wenn Sie nur eines davon ändern, ist es eine Frage der Praktikabilität und des "Mühens/Nicht-Mühens", die Daten beim Schreiben des Codes zu ändern.

 
Roman:

Können Sie den Sinn der Erstellung eines dynamischen Objekts mit dem Operator new erklären?

Bei der automatischen Erstellung eines Objekts wird das Klassenobjekt auf dem Stapel erstellt und ist in Bezug auf die Ausführungszeit schneller als ein dynamisches Objekt.
Bei der dynamischen Erstellung eines Objekts wird ein Klassenobjekt im Speicher (im Heap) unter Einbeziehung des OS-Speichermanagers erstellt; der Prozess ist langsamer.

Hier sind die Fragen:
Wenn die automatische Erstellung schneller ist, warum ist es dann besser, dynamische Objekte zu verwenden?
Explizite Kontrolle der Speicherzuweisung?
Einen möglichen Stapelüberlauf beseitigen?
Und nicht unerwartet einen Gegenstand zu verlieren?
Denn wenn der Stapel überläuft, wird das Objekt automatisch gelöscht?

Guten Tag. Computerspeicher hat die gleiche Leistung, unabhängig davon, ob er im Stack- oder Heap-Kontext verwendet wird. Die dynamische Speicherverwaltung selbst hängt von der Implementierung des Müllsammlers ab: Sie kann z. B. eine Referenzzählung wie in Python (langsamere Variante) oder eine Analyse der Epochen der Objekterzeugung mit Traversierung des Ausführungsgraphen im Hintergrundprozess (Net CLR) sein. Welche Variante in MQL verwendet wird, ist nicht bekannt, aber wir können davon ausgehen, dass sie äußerst effizient ist, da der Benutzer von MQL5 direkten Zugriff auf den Löschoperator hat, was die Arbeit von GC selbst stark vereinfacht. Daher sind Ihre Bedenken bezüglich des Overheads bei der Verwendung von new unbegründet - Sie können gerne dynamischen Speicher verwenden.

Was den "Stapelüberlauf" betrifft, so kann dieser Fall in modernen Systemen nur dann eintreten, wenn eine komplexe Rekursion verwendet wird oder ein Fehler im rekursiven Algorithmus gemacht wird. Ein modernes Programm arbeitet immer im OC-geschützten Modus im virtuellen Adressraum, mit dynamischem Laden von Speicherseiten, also keine Sorge: der Stack wird nicht überlaufen:)