Fragen zu OOP in MQL5 - Seite 35

 
Roman:

Wenn das Objekt seine Aufgabe erfüllt hat, warum sollte es dann im Speicher bleiben?
Wird es nicht zu einem Speicherleck kommen?

Das ist der Fall, vor allem, wenn er auch bei OnDeinit nicht gelöscht wird.
Sie müssen sie nicht speichern, wenn Sie sie wirklich nicht mehr brauchen. Häufiger kommt es jedoch vor, dass ein Objekt in einer Iteration erstellt und verwendet wird... Und dann bei der zweiten Wiederholung... Und so weiter. Und dann wird unter bestimmten Bedingungen ein weiteres Objekt derselben Klasse erstellt, und schon arbeitet man mit zwei oder mehr Objekten dieser Klasse, von denen jedes während der gesamten Lebensdauer des EA benötigt wird.

 
BlackTomcat:

Dies geschieht vor allem dann, wenn sie auch bei OnDeinit nicht gelöscht wird.
Sie müssen sie nicht speichern, wenn Sie sie wirklich nicht mehr brauchen. Häufiger kommt es jedoch vor, dass ein Objekt in einer Iteration erstellt und verwendet wird... Und dann bei der zweiten Wiederholung... Und so weiter. Und dann wird unter bestimmten Bedingungen ein weiteres Objekt derselben Klasse erstellt, und schon arbeitet man mit zwei oder mehr Objekten dieser Klasse, von denen jedes während der gesamten Lebensdauer des EA benötigt wird.

Sie wollen also sagen, dass ein kontrolliertes Speicherleck besser ist als die Neuerstellung von Objekten?
Das heißt, Zeitersparnis im Austausch gegen kontrollierte Dämonen?
Es ist gefährlich, sie später nicht zu verlieren.

 

geschrieben unter Verwendung der Vorlagehttps://www.mql5.com/ru/forum/85652/page24#comment_13054686 des Experten

eine recht flexible Vorlage, ermöglicht das Hinzufügen verschiedener "Pluspunkte" in "2 Klicks" und der Code stellt sich als lesbar und logisch, aber... Ich bin zu dem diskutierten Paradigma zurückgekehrt, dass eine gute Klasse, nun ja, keine statischen Methoden haben sollte

Das klingt in der Theorie schön, aber in der Praxis... Meiner Meinung nach nicht, zumindest nicht bei MMS-Problemen, imho.

Gemäß der Vorlage wurde die EA-Klasse geschrieben und eine öffentliche Methode wird in OnTick() gestartet. Aber während der Initialisierung des EAs möchte ich prüfen, ob es offene Aufträge gibt und diese aufheben:

1. eine Funktion im OnTick() unten schreiben, die, wenn sie über den Assistenten einen offenen Auftrag findet, ein EA-Objekt erstellt; wenn kein Auftrag gefunden wird, wird das EA-Objekt gemäß der Grundlogik initialisiert - das EA-Objekt wird nur zur Handelszeit erstellt und implementiert die Logik des TS in der Zukunft

2. eine statische Klasse in EA schreiben, die die Punkte 1 und 2 implementiert


Im Wesentlichen sind die Punkte 1 und 2 gleich, der Unterschied ist, dass ich in Schritt 1 eine Funktion hinzufüge, die nur während der Initialisierung des EA (dem ersten Lauf) Sinn machen würde, aber imho überlastet sie den Code - eine Funktion wird einmal für die gesamte Ausführung des Programms aufgerufen!

wenn Sie eine statische Methode ( pp.2 ) machen, dann ist es logisch und lesbar - die Methode wird nur für die Initialisierung benötigt und definiert den Zeitpunkt, an dem das EA-Objekt erstellt werden soll - Sie sollten dieser Methode nur eine magische Zahl übergeben.


Meiner Meinung nach zu verbieten, statische Methoden zu verwenden, wenn es praktisch ist... um es gelinde auszudrücken: falsch!

 
Igor Makanu:

Statische Methoden unterscheiden sich von Funktionen nur durch ihren Anwendungsbereich.


Diese Praxis ist gefährlich

input int inInput = 0;

const bool Init = EventSetTimer(1);

void OnTimer()
{
  static int Input = inInput;
  
  Print(Input);
}


Wenn Sie den Eingang ändern, während der EA läuft, wird der Eingang nicht geändert.

Dementsprechend ist sie mit folgenden Problemen behaftet

input long inMagic = 0;

void OnTick()
{
  static ORDER Orders[]; // Список ордеров по мэджику или что-то подобное, зависящая от входных.
}
 
fxsaber:

Wenn Sie die Eingabe ändern, während EA läuft, wird die Eingabe nicht geändert.

Ich bin mir dessen bewusst, und in meinem TS können Sie die Eingabeparameter nicht ändern, während EA arbeitet, die Laufzeit ist von der Logik des TS getrennt

Meine Frage ist rein theoretisch, ich möchte den Code nicht überladen, also suche ich nach einer Möglichkeit, den TS nach einem Absturz wiederherzustellen, bisher sehe ich das so:

input int EAMagicNumber = 12345;
class CEA
{
public:
   static bool       NeedRecovery(int magic_)            {   return(true);    }
   bool              Recovery(int magic_,int inputparam) {   return(true);    }
                     CEA()                               {                    }
                     CEA(int inputparam)                 {                    }
                    ~CEA()                               {                    }
};

CEA *ea;

void OnStart()
{
   if(CheckPointer(ea)==POINTER_INVALID)
   {
      if(CEA::NeedRecovery(EAMagicNumber))   //если нашли открытые ордера с магиком
      {
         ea = new CEA();         // создали объект
         ea.Recovery(EAMagicNumber,11111);   // запустили восстановление ТС
      }else ea = new CEA(2222222);           //обычный запуск
   }
 
Igor Makanu

Es ist sinnvoller, diese Logik in den Konstruktor zu verlagern.

 
fxsaber:

Statische Methoden unterscheiden sich von Funktionen nur durch ihren Anwendungsbereich.

Falsch: Sie haben auch Zugriff auf nicht-öffentliche Mitglieder und Methoden der Klasse.
 
TheXpert:
auch den Zugang zu nicht-öffentlichen Mitgliedern und Methoden der Klasse.

Hier liegt ein terminologisches Missverständnis vor. Beim "Sichtbarkeitsbereich" geht es nicht nur darum, wer die Methode sieht. Aber auch, was er selbst sieht.

 
fxsaber:

Hier liegt ein terminologisches Missverständnis vor.

Schließlich handelt es sich bei Sichtbarkeit und Zugang um unterschiedliche Konzepte, die am besten nicht verwechselt werden sollten.
 
fxsaber:

Es ist sinnvoller, diese Logik in den Konstruktor zu integrieren.

Ja, das ist eine bessere Lösung! Es gibt also eine Methode weniger

So sollte es auch sein:

input int EAMagicNumber = 12345;
class CEA
{
public:
   static bool       NeedRecovery(int magic_)            {   return(true);    }  //тут проверки
                     CEA(int magic_)                     {                    }  //это обычный запуск если все ОК
                     CEA(int magic_, int recoveryparam)  {                    }  //тут аварийное восстановление
                    ~CEA()                               {                    } };

CEA *ea;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
{  if(CheckPointer(ea)==POINTER_INVALID)
   {  if(CEA::NeedRecovery(EAMagicNumber))   //если нашли откртые ордера с магиком
      {  
         ea = new CEA(EAMagicNumber,11111);  // запустили востановление ТС
      }
      else ea = new CEA(EAMagicNumber);      //обычный запуск
   } 
}
TheXpert:
schließlich sind Sichtbarkeit und Zugang unterschiedliche Konzepte, die man am besten nicht verwechseln sollte
Deshalb habe ich eine Frage, wo würde ich einen Weg, um zu erkennen, dass der letzte Lauf abgestürzt ist, jetzt meine Code-Struktur ist kompakt, alles ist eindeutig nach dem Muster, das ich oben gezeigt