Hilfe bei OOP

 

Ich mache einen solchen Kurs.

class Strategy1
{
        Strategy1();
 };

class Strategy2
{
        Strategy (string sym);
}

Jetzt möchte ich ein Objekt-Array aufrufen:

Strategy1 S[10];  // компилируется 
Strategy2 Z("EURUSD")[10]; // не компилируется 

Wie kann man dann schnell ein Array von Objekten erstellen, wenn der Konstruktor Parameter auf globaler Ebene hat?

Erstellen Sie zum Beispiel zuerst Objekte, indem Sie den Konstruktor ändern, und wie kann ich dann die Objekte in OnInit durch Symbole ersetzen?

Vielleicht gibt es eine einfachere Lösung?

 

Ich persönlich verwende in solchen Fällen die Funktion Init() für Objekte.

Zunächst wird ein Array erstellt, und dann wird die Funktion Init() für alle Objekte im Array aufgerufen, wobei alle Parameter gesetzt werden können.

Die Initialisierung mit einer separaten Funktion ermöglicht die Neuinitialisierung von Objekten, und wenn Sie im Konstruktor initialisieren, können Sie das Objekt nicht neu initialisieren.

 
Georgiy Merts #:

Ich persönlich verwende in solchen Fällen die Funktion Init() für Objekte.

Zunächst wird ein Array erstellt, und dann wird die Funktion Init() für alle Objekte im Array aufgerufen, wobei alle Parameter gesetzt werden können.

Die Initialisierung mit einer separaten Funktion ermöglicht die Neuinitialisierung von Objekten, und wenn Sie es im Konstruktor initialisieren, ist es unmöglich, das Objekt neu zu initialisieren.

Nun, so habe ich es mir vorgestellt. Danke!

 

Ein weiterer Punkt. Es ist besser, Arrays von Objekten mit Hilfe eines Zeigers zu erstellen. Andernfalls erhalten Sie ein Array im Stapelspeicher, das sehr klein ist:

Strategy2 *pZ[]; 
if (ArrayResize(pZ, 10) != 10)
{
   Alert("Memory allocation error");
   return;
}

for (int i = 0; i < 10; ++i)
{
   pZ[i] = new Strategy2("EURUSD"); 
   if (CheckPointer(pZ) == POINTER_INVALID)
   {
      Alert("Class instantiation error");
      return;
   }
}
 
Ihor Herasko #:

Ein weiterer Punkt. Es ist besser, Arrays von Objekten mit Hilfe eines Zeigers zu erstellen. Andernfalls erhalten Sie ein Array im Stapelspeicher, das sehr klein ist:

Ein Beispiel für ein mögliches Problem wäre schön.

 
Ihor Herasko #:

Ein weiterer Punkt. Es ist besser, Arrays von Objekten mit Hilfe eines Zeigers zu erstellen. Andernfalls erhalten Sie ein Array im Stapelspeicher, das sehr klein ist:

Autsch.

 
Das ist keine große Sache.
 
fxsaber #:

Ein Beispiel für ein mögliches Problem wäre gut.

Das ist kein Problem und schon gar nicht ein potenzielles Problem. Das liegt nur an den Eigenheiten der Speicherverwaltung in MT. Hier ist ein statisches Array:

#define               ARRAY_SIZE           int(60000000)
class Test
{
public:
   int               nA;
   double            fB;
   datetime          dtC;

                     Test(void)
                       : nA(0)
                       , fB(1.0)
                       , dtC(__DATETIME__)
                     {
                     };
};

Test classTest[ARRAY_SIZE];                   // 'classTest' - global variables section is too large
 
void OnStart()
{
}

Und hier ist ein dynamisches Array:

#define               ARRAY_SIZE           int(60000000)
class Test
{
public:
   int               nA;
   double            fB;
   datetime          dtC;

                     Test(void)
                       : nA(0)
                       , fB(1.0)
                       , dtC(__DATETIME__)
                     {
                     };
};

Test *pClassTest[];
 
void OnStart()
{
   if (ArrayResize(pClassTest, ARRAY_SIZE) != ARRAY_SIZE)
   {
      Alert("Not enought memory");
      return;
   }
   
   for (int i = 0; i < ARRAY_SIZE; ++i)
   {
      pClassTest[i] = new Test();
      if (CheckPointer(pClassTest[i]) == POINTER_INVALID)
      {
         Alert("Class instantiation error");
         return;
      }
   }

   for (int i = 0; i < ARRAY_SIZE; ++i)
      delete pClassTest[i];
}

In diesem Fall wird alles kompiliert und funktioniert.

 
Ihor Herasko #:

Das ist kein Problem, geschweige denn ein potenzielles Problem. Das liegt nur an den Eigenheiten der Speicherverwaltung in MT. Hier ist ein statisches Array:

Und hier ist ein dynamisches Array:

In diesem Fall wird alles kompiliert und funktioniert.

Was hat der Stapel damit zu tun? Im ersten Fall haben Sie versucht, statisch (in der Kompilierungsphase) einen großen Speicherblock in einem Heap zuzuweisen, und der Compiler hat Sie zu Recht vor die Stirn getreten, weil es in Wirklichkeit nicht ganz klar ist, ob Sie so viel Speicher zuweisen können oder nicht.

Im zweiten Fall weisen Sie bereits zur Laufzeit einen großen Teil des Speichers zu. Und es ist sofort klar, ob man es zuweisen kann oder nicht, denn das Programm arbeitet bereits mit einer bestimmten Ressource des Rechners (Speicher).

Und was haben Zeiger damit zu tun? In mql gibt es zwei Arten von Arrays: vordefinierte zur Kompilierzeit und dynamische. Nicht nur Zeiger *, sondern auch normale Klassenfelder können auf dynamische Arrays zeigen. Die Verwendung von Zeigern ist hier also absolut nicht gerechtfertigt.

s.e. Seltsamer Eindruck des Codes, wie Zeiger, Klassen, Makros - mit völligem Unverständnis dessen, was vor sich geht.

 
Ihor Herasko #:

Das ist kein Problem, geschweige denn ein potenzielles Problem. Das liegt nur an den Eigenheiten der Speicherverwaltung in MT. Hier ist ein statisches Array:

Und hier ist ein dynamisches Array:

In diesem Fall wird alles kompiliert und funktioniert.

Falsches Beispiel, es ist nur eine Einschränkung des Compilers, die nichts aussagt, die Entwickler haben das einfach so beschlossen.

Wenn es zwei Versionen gäbe - die eine hat ein großes statisches Array und die andere ein kleines - und siehe da, wenn das Programm funktioniert, treten in einem Fall Probleme auf, zum Beispiel beim rekursiven Aufruf einer Funktion, während sie im anderen Fall unter den gleichen Bedingungen nicht auftreten. Dann könnte man eine Schlussfolgerung ziehen ... über den Schaden von frisch gepresstem Saft)))

 
Vasiliy Sokolov #:

Was hat der Stapel damit zu tun? Im ersten Fall haben Sie versucht, statisch (in der Kompilierungsphase) einen großen Speicherblock im Heap zuzuweisen, und der Compiler hat Sie zu Recht vor den Kopf gestoßen, weil es in der realen Welt überhaupt nicht klar ist, ob Sie so viel Speicher zuweisen können oder nicht.

Im zweiten Fall weisen Sie bereits zur Laufzeit einen großen Teil des Speichers zu. Und es ist sofort klar, ob man es zuweisen kann oder nicht, denn das Programm arbeitet bereits mit einer bestimmten Ressource des Rechners (Speicher).

Und was haben Zeiger damit zu tun? In mql gibt es zwei Arten von Arrays: vordefinierte zur Kompilierzeit und dynamische. Nicht nur Zeiger *, sondern auch normale Klassenfelder können auf dynamische Arrays zeigen. Die Verwendung von Zeigern ist hier also absolut nicht gerechtfertigt.

s.e. Seltsamer Eindruck des Codes, wie Zeiger, Klassen, Makros - mit völligem Unverständnis dessen, was vor sich geht.

Wenn wir das Beispiel ein wenig abändern, es lokal deklarieren und eine nicht so schreckliche Zahl einsetzen, sagt uns der Compiler direkt, wo das Problem liegt:

#property strict
#define               ARRAY_SIZE           int(140000)

class Test
{
   
public:
   int               nA;
   double            fB;
   datetime          dtC;

                     Test(void)
                       : nA(0)
                       , fB(1.0)
                       , dtC(__DATETIME__)
                     {
                     };
};
 
void OnStart()
{
   Test classTest[ARRAY_SIZE];    // the size of local variables is too large
}
Wenn Sie sich mit Renate streiten wollen, können Sie das gerne tun.
the size of local variables is too large (more than 512kb)
the size of local variables is too large (more than 512kb)
  • 2014.02.08
  • www.mql5.com
Здравствуйте! Написал индикатор на mql4. Все работало...
Grund der Beschwerde: