Fragen zu OOP in MQL5 - Seite 8

 
Igor Makanu:

schreiben Sie nicht löschen - alles wird richtig funktionieren, diese Sünde (ich meine Aberglaube)) ) übernimmt das Terminal und murmelt in sein Protokoll "48 Bytes an ausgelaufenem Speicher", dann "2 Objekte des Typs CX übrig" und "ungelöschte Objekte übrig".

HH: in der Indikatorvorlage gibt es kein Deinit() - das ist ärgerlich

Warum nicht ein Objekt und nicht einen Zeiger erstellen? Dann nuschelt es auch nicht - das Terminal-Subsystem spürt es auf und nagelt es bei Bedarf fest.

 
Dmitry Fedoseev:

Es funktioniert auch ohne Löschen, aber es ist sinnlos. Aber kümmert sich das Terminal um dieses Problem? Er meldet nur Speicherlecks, widmet sich aber nicht denselben Objekten.

Das Terminal kümmert sich um das Löschen von Objekten, die von new erstellt wurden, falls Zeiger auf sie in einem dem Terminal bekannten Objekt, z.B. ArrayObj, List, etc..., abgelegt sind.

 
Artyom Trishkin:

Warum nicht ein Objekt statt eines Zeigers erstellen? Dann nuschelt es auch nicht - das Terminal-Subsystem spürt es auf und nagelt es bei Bedarf fest.

dennhttps://www.mql5.com/ru/forum/85652/page7#comment_12329866

Artyom Trishkin:

Terminal kümmert sich um das Löschen von Objekten, die von new erzeugt wurden, falls Zeiger auf sie in einem dem Terminal bekannten Objekt abgelegt sind, z.B. ArrayObj, List, etc...

nicht immer geeignet für die unbeaufsichtigte Zerstörung, aber ich muss nachsehen, vielleicht irre ich mich - ich verwende CObject selten

 

Nun, dies ist ein sehr spezieller und grotesk vereinfachter Fall, wie ich finde. Ein Objekt zu erstellen, das nicht geändert werden kann, so dass man, um seine Felder zu ändern, es festnageln und ein neues erstellen muss...

Und wenn wir einige Objektfelder ändern und andere Felder mit notwendigen Informationen belassen müssen? IMHO ist es besser, sich um die Interaktivität und die Verwaltbarkeit der einzelnen Objekte zu kümmern (dank Vererbung), als bei jedem Niesen mit einer Pistole zu sitzen und Kaninchen zu erschießen.

Obwohl, um fair zu sein - manchmal ist es schneller, zu töten und ein neues zu erstellen, als das gewünschte Objekt unter einer großen Anzahl zu suchen und es zu ändern. Es sei denn, es gibt einen direkten Link zu ihr...

 
Artyom Trishkin:

Nun, dies ist ein sehr spezieller und grotesk vereinfachter Fall, wie ich finde. Ein Objekt zu erstellen, das absolut unveränderlich ist, so dass man, um die Werte seiner Felder zu ändern, es festnageln und ein neues Objekt erzeugen muss...

Und wenn wir einige Objektfelder ändern und andere Felder mit notwendigen Informationen belassen müssen? IMHO ist es besser, sich um die Interaktivität und die Verwaltbarkeit der einzelnen Objekte zu kümmern (dank Vererbung), als bei jedem Niesen mit einer Pistole zu sitzen und Kaninchen zu erschießen.

Obwohl, um fair zu sein - manchmal ist es schneller, zu töten und ein neues zu erstellen, als aus einer großen Anzahl von Einträgen den gewünschten herauszusuchen und ihn zu ändern. Es sei denn, Sie haben einen direkten Link zu ihr...

hmmm, du liegst völlig daneben.... ja, aber nicht auf diese Weise ))))

was auch immer bequem ist, das ist die richtige Art, es zu benutzen! - und diese Beispiele aus dem "ersten C++-Lehrbuch" können Sie Ihr ganzes Leben lang anwenden.... Als Beispiel habe ich einen anständigen Teil des Codes von @fxsaber auseinandergenommen und mich gezwungen, #define so oft wie möglich zu verwenden - der Code wurde nicht nur kürzer, sondern wirklich lesbarer und eliminierte Tippfehler - lehren sie so viel in C++-Büchern? ;)


Artyom Trishkin:

Obwohl, um fair zu sein - manchmal ist es schneller, einen zu töten und einen neuen zu erstellen, als einen benötigten unter einer großen Anzahl zu suchen und ihn zu ändern. Natürlich, wenn es keine direkte Ansprache gibt...

und über die Grundlagen des Buches... Die guten Zuchtregeln besagen: deklariere eine Variable und initialisiere sie sofort (so kannst du Fehler beim Debuggen vermeiden), in OOP dient der Konstruktor für diese Zwecke - du hast ein Objekt erstellt und initialisierst alles

wenn Sie "den gesamten Code nach einem einfachen Objekt ziehen" müssen, benötigen Sie eine Methode, um alle Klassenfelder neu zu initialisieren - warum dies duplizieren? - töten/erzeugen = Ergebnis.... aber auch hier ist es eine Frage des Geschmacks und der Religion.

 
Igor Makanu:

dennhttps://www.mql5.com/ru/forum/85652/page7#comment_12329866

Ich fühle mich nicht immer wohl mit der unbeaufsichtigten Zerstörung, aber ich werde das überprüfen müssen, vielleicht liege ich ja falsch - ich verwende selten CObject

Aber Sie verwenden Listen. Und dort ist es dasselbe. Nun, wenn das Flag der Speicherverwaltung FreeMode() für die Liste nicht zurückgesetzt wird - in diesem Fall wird das Terminal nicht tracen - wird alles vom Benutzer übernommen. Aber diese Situation ist notwendig, um in der Lage zu sein, zu ändern, zu löschen, zu sortieren und etwas anderes mit einer Kopie der Liste zu tun - in der Tat ist die Liste mit Zeigern auf Objekte erstellt, und wenn Sie eine neue Liste eine Kopie von einer der Listen zu erstellen, und beginnen, Objekte in der neuen Liste zu ändern (es Zeiger auf Objekte), dann in der ursprünglichen Liste auch Objekte geändert werden (weil wir mit Zeigern arbeiten). Das ist, um das Original zu behalten und fiddle mit seiner Kopie, dann müssen Sie die Flagge der Speicherverwaltung für eine Kopie fallen zu lassen: FreeMode(false) - dann wird die Kopie eine unabhängige Kopie, und Sie können sicher mit Objekten in ihr arbeiten, ohne das Original zu beeinflussen. Und denken Sie daran, dass, wenn Sie die Bindung der Listenkopie an das Terminalsubsystem aufheben, wir nun selbst für das Löschen der Listenobjekte verantwortlich sind. Man kann sie entweder verfolgen und in OnDeinit() löschen, das ist der einfachste Fall und wenn die Kopierliste vorher bekannt ist, oder eine Objektliste erstellen, die neu erstellte, vorher nicht bekannte Listen immer mit dem Flag der manuellen Speicherverwaltung versieht. Dann wird das Terminal dieses Listenobjekt verfolgen und die darin gestapelten Listen korrekt löschen.

 
Artyom Trishkin:

Das Terminal übernimmt das Löschen von Objekten, die von new erzeugt wurden, falls Zeiger auf sie in einem dem Terminal bekannten Objekt, z.B. ArrayObj, List, etc..., abgelegt sind.

Dann wird es auch keine Leckmeldung geben.

 
Dmitry Fedoseev:

Dann wird es auch keine Meldung über ein Leck geben.

Ja, das wird es nicht. Denn es wird kein Leck geben.

Wenn wir irgendwo ein neues Objekt erstellt und einen Zeiger darauf erhalten haben, müssen wir dieses Objekt mit dem angegebenen Zeiger löschen. Das bedeutet, dass wir den Zeiger verfolgen müssen. Für diesen Zweck sind die Listen oder Arrays von Zeigern auf Objekte, die in SB angeboten werden, sehr gut geeignet. Sie können sich aber auch um die Verfolgung und Kontrolle der neu erstellten Objekte kümmern. Aber warum sollte ich Tonnen von Code schreiben, wenn er bereits vorhanden ist?

 
Artyom Trishkin:

dann sollten sie dieses Objekt mit diesem Zeiger löschen.

Aber warum sollte ich Tonnen von Code schreiben, wenn er bereits vorhanden ist?

Alles, was Sie übersehen haben, wird vom Terminal gemeldet und die Stelle, an der Sie es löschen können, ist ebenfalls bekannt - OnDeint() .... Diese Diskussion läuft also auf eine Diskussion über ein kugelförmiges Pferd in einem Vakuum hinaus? )))

 
Igor Makanu:

hmm, das soll wohl ein Scherz sein..... so, aber nicht so ))))

da es bequem ist, sollten Sie es so verwenden! - und diese Beispiele aus dem "ersten s++-Lehrbuch" können Sie Ihr ganzes Leben lang in Ihre Erfahrung einfließen lassen.... Als Beispiel habe ich einen guten Teil des Codes von @fxsaber auseinandergenommen und mich selbst dazu gebracht, so viel wie möglich #define zu verwenden - die Codes wurden nicht nur kürzer, sondern wirklich lesbarer und typofreier - lehren sie das in C++-Büchern? ;)


Und über die Grundlagen des Buches... Gute Züchtungsregeln besagen: eine Variable ausrufen und sofort initialisieren (so kann man Fehler bei der Fehlersuche vermeiden), in OOP dient der Konstruktor diesem Zweck - man erzeugt ein Objekt und initialisiert alles

wenn Sie "den gesamten Code nach einem einfachen Objekt ziehen" müssen, benötigen Sie eine Methode zur Neuinitialisierung aller Klassenfelder - warum dies duplizieren? - töten/erzeugen = Ergebnis.... aber auch hier ist es eine Frage des Geschmacks und der Religion.

Ich spreche nicht von einer vollständigen Neuinitialisierung eines Objekts, sondern von einer teilweisen - wenn ein paar Felder geändert werden müssen und die restlichen paar Dutzend Felder noch die benötigten Informationen speichern... Wir können Felder ändern oder auch nicht, aber wir brauchen Methoden, um sie zu ändern. Es sei denn, es handelt sich wieder um ein einfaches Objekt mit einem Feld. Wenn es zwei oder mehr sind, müssen Sie vielleicht schon einen ändern und die anderen unverändert lassen.

Aber vielleicht reden wir über unterschiedliche Dinge?