PLO. Fragen zur Anwendung - Seite 11

 
Interesting:

Wie gut es ist, lesen zu können... :)

Auch kein schlechter Ansatz, obwohl, wie ich verstanden habe, beide Ansätze auf der Übermittlung/Lesung nur eines Parameters (wenn auch unterschiedlicher Art) beruhen.

Aber wie löst man das Problem, wenn man viele Parameter hat und nicht alle in einer Basisklasse unterbringen kann?

Soweit ich verstanden habe, müssen Sie einen Index des Parameters eingeben, den Sie übergeben (Sie können auch ein Array in einer Klasse erstellen, in dem die Parameter nach Index gespeichert werden)?

Ich verstehe es auch nicht...

In meinem Beispiel gibt es einen Index, nur ist er nicht numerisch in einer expliziten Form, sondern ein enum....

 

Vergessen Sie es, das ist es nicht wert.

 

Interesting:

Yedelkin:

Im Allgemeinen hathttps://www.mql5.com/ru/forum/3566/page6#comment_58280 nach einer Diskussion über das Problem einen Antrag an den SR geschickt.

1. Ich weiß es nicht, ich weiß es nicht.

Ich glaube nicht, dass die Entwickler bestimmte Schritte unternehmen und die Funktionalität zugunsten der Sicherheit opfern werden (und das zu Recht, einerseits).

Rückmeldung.

Die Bewerbung sah folgendermaßen aus:
...

Anregung:

1. Erläutern Sie den Abschnitt "Polymorphismus" im Handbuch "Polymorphismus" im Hinblick darauf, wie Array Shapes[10] korrekt mit Instanzen von Klassen gefüllt werden, die von CShape abgeleitet sind (geben Sie ein Beispiel).

2. Prüfen Sie, ob die Zeichenkette richtig geschrieben ist:

CShape[10] shapes;                       // массив объектов CShape

3. Erläutern Sie, ob bei der Deklaration von Klassen geschweifte Klammern unmittelbar nach dem Namen der deklarierten Klasse gesetzt werden sollen oder nicht:

class CShape{};

class CCircle{} :public CShape

class CSquare{} :public CShape

Antwort:

Rashid Umarov 2011.04.11 15:17

Zum Zeitpunkt der Erstellung der Hilfe waren einige Punkte noch nicht klar dokumentiert. Wir werden diesen Punkt beheben und den richtigen Code hinzufügen. Vielen Dank für Ihre Nachricht.

Eine ausführliche Beschreibung wird der Hilfe hinzugefügt, hier ist ein Auszug daraus:

Wir nehmen an, dass unser Programm Objekte unterschiedlichen Typs (CCircle und CSquare) verwendet, die jedoch von einem Basistyp CShape geerbt wurden. Polymorphismus ermöglicht es uns, ein Array von Objekten des Basistyps CShape zu erstellen, aber wenn wir dieses Array deklarieren, sind die Objekte selbst noch unbekannt und ihr Typ ist nicht definiert.

Die Entscheidung, welche Art von Objekt in jedem Element des Arrays enthalten sein wird, wird während der Ausführung des Programms getroffen. Dies impliziert eine dynamische Objekterzeugung für die entsprechenden Klassen und damit die Notwendigkeit, Objektzeiger anstelle der Objekte selbst zu verwenden.

Um Objekte dynamisch zu erzeugen, wird der new-Operator verwendet; jedes solche Objekt muss unabhängig und explizit durch den delete-Operator gelöscht werden. Daher deklarieren wir ein Array von Zeigern des Typs CShape und erstellen ein Objekt des erforderlichen Typs für jedes seiner Elemente(new_class_name), wie im Beispielskript gezeigt:

//+------------------------------------------------------------------+

//| Script program start function                                    |

//+------------------------------------------------------------------+

void OnStart()

  {

//--- объявим массив указателей объектов базового типа 

   CShape *shapes[5];   // массив указателей на объекты CShape



//--- здесь заполняем массив производными объектами

//--- объявим указатель на объект типа CCircle

   CCircle *circle=new CCircle();

//--- задаем свойства объекта по указателю circle

   circle.SetRadius(2.5);

//--- поместим в shapes[0] значение указателя

   shapes[0]=circle;



//--- создаем еще один объект CCircle и запишем его указатель в shapes[1]

   circle=new CCircle();

   shapes[1]=circle;

   circle.SetRadius(5);



//--- тут мы намеренно "забыли" задать значение для shapes[2]

//circle=new CCircle();

//circle.SetRadius(10);

//shapes[2]=circle;



//--- для неиспользуемого элемента установим значение NULL

   shapes[2]=NULL;



//--- создаем объект CSquare и запишем его указатель в shapes[3]

   CSquare *square=new CSquare();

   square.SetSide(5);

   shapes[3]=square;



//--- создаем объект CSquare и запишем его указатель в shapes[4]

   square=new CSquare();

   square.SetSide(10);

   shapes[4]=square;



//--- массив указателей есть, получим его размер

   int total=ArraySize(shapes);

//--- пройдем в цикле по всем указателям в массиве 

   for(int i=0; i<5;i++)

     {

      //--- если по указанному индексу указатель является валидным

      if(CheckPointer(shapes[i])!=POINTER_INVALID)

        {

         //--- выведем в лог тип и площадь фигуры

         PrintFormat("Объект типа %d имеет площадь %G",

               shapes[i].GetType(),

               shapes[i].GetArea());

        }

      //--- если указатель имеет тип POINTER_INVALID

      else

        {

         //--- сообщим об ошибке

         PrintFormat("Объект shapes[%d] не инициализирован! Его указатель %s",

                     i,EnumToString(CheckPointer(shapes[i])));

        }

     }



//--- мы должны самостоятельно уничтожить все созданные динамические объекты

   for(int i=0;i<total;i++)

     {

      //--- удалять можно только объекты, чей указатель имеет тип POINTER_DYNAMIC

      if(CheckPointer(shapes[i])==POINTER_DYNAMIC)

        {

         //--- сообщим об удалении

         PrintFormat("Удаляем shapes[%d]",i);

         //--- уничтожим объект по его указателю

         delete shapes[i];

        }

     }

  }


Beachten Sie, dass Sie beim Löschen eines Objekts mit dem delete-Operator den Typ seines Zeigers überprüfen sollten. Sie können nur Objekte mit dem Zeiger POINTER_DYNAMIC löschen, bei Zeigern eines anderen Typs erhalten Sie einen Fehler.

Ich denke, dieses Beispiel deckt die Idee der Erstellung eines Arrays von Zeigern vollständig ab.
Rashid Umarov 2011.04.11 10:31

Danke für den Beitrag, wir haben №2 und №3 korrigiert. Wird in neuen Versionen der Hilfe enthalten sein



 

Frage. Die Standardbibliothek verwendet die folgenden Zeilen

void CTrade::Request(MqlTradeRequest& request) const
  {...}

Das Referenzhandbuch sagt: "const specifier ist nicht anwendbar auf Mitglieder von Strukturen und Klassen". Was bedeutet die Verwendung von const in einer Klassenmethode, und welche Regeln gibt es für die Verwendung in solchen Fällen?

Документация по MQL5: Стандартная библиотека
Документация по MQL5: Стандартная библиотека
  • www.mql5.com
Стандартная библиотека - Документация по MQL5
 

Yedelkin:

...............

Was bedeutet die oben beschriebene Verwendung von const in einer Klassenmethode, und welche Regeln gibt es für die Verwendung in solchen Fällen?

Oh ja, das habe ich mich auch schon lange gefragt. Ich möchte die Sprache auf sinnvolle Weise verwenden und mir der "Spielregeln" bewusst sein.
 
Yedelkin:

Frage. Die Standardbibliothek verwendet die folgenden Zeilen

Das Referenzhandbuch sagt: "const specifier ist nicht anwendbar auf Mitglieder von Strukturen und Klassen". Was bedeutet die Verwendung von const in einer Klassenmethode, und welche Regeln gibt es für die Verwendung in solchen Fällen?

Ein Struktur-/Klassenmitglied ist eine Sache, aber eine Methode ist eine andere.

Eine Methode, die als const beschrieben wird, bedeutet, dass sie den Zustand/die Mitglieder ihrer Klasse nicht verändert. Das heißt, nach dem Aufruf einer solchen Methode bleibt der interne Zustand der Klasse unverändert. Es wird verwendet, um dem Compiler zusätzlich mitzuteilen, dass er auf Versuche, Klassenmitglieder zu ändern, prüfen soll.

 
Renat:

Ein Struktur-/Klassenmitglied ist eine Sache, eine Methode eine andere.

Eine Methode, die als const beschrieben wird, bedeutet, dass sie den Zustand/die Mitglieder ihrer Klasse nicht verändert. Das heißt, der interne Zustand der Klasse bleibt nach dem Aufruf dieser Methode unverändert. Es wird verwendet, um dem Compiler zusätzlich mitzuteilen, dass er auf Versuche, Klassenmitglieder zu ändern, prüfen soll.

Wow. Ich danke Ihnen! Und ich habe mir den Kopf zerbrochen.

 
TheXpert:
Übrigens, eine logische Frage, wenn wir schon beim Thema sind - es gibt kein Handbuch und es wird auch nicht erwartet?

Wie könnte sie verwendet werden? Weil die Themen nicht miteinander interagieren,

Wenn die Daten frei zwischen den Threads übertragen werden könnten, wäre eine solche Anweisung in der Tat erforderlich.

 
Verdammt, ich dachte, ich hätte etwas Falsches geschrieben :) jetzt weiß ich, was es ist. Natürlich nicht flüchtig, sondern veränderbar:))
 
class COracleTemplate
  {
private:
public:
   string            filename;
                     COracleTemplate(){Init();};
                    ~COracleTemplate(){DeInit();};
   virtual void      Init(){filename=this.Name();Print("loadSettings from ",filename);};
   virtual void      DeInit(){Print("saveSettings to ",filename);};
   virtual string    Name(){return("Prpototype");};
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CCO2:public COracleTemplate
  {
   virtual string    Name(){return("CO2");};
  };
class CH2O:public COracleTemplate
  {
   virtual string    Name(){return("H2O");};
  };
COracleTemplate* CO2,*H2O;
void OnStart()
  {
   CO2=new CCO2;
   Print(CO2.Name()," filename=",CO2.filename);
   delete CO2;
   
   H2O=new CH2O;
   Print(H2O.Name()," filename=",H2O.filename);
   delete H2O;
   
  }

Guten Tag.

Eine solche Frage

Zum obigen Code

Was habe ich falsch gemacht oder ist es generell unerreichbar im MT5?

Ich möchte (wie ich denke, ist offensichtlich) - um überschriebene Namen in Dateinamen-Variablen zu erhalten...