PLO. Fragen zur Anwendung - Seite 12

 
GreyCardinal:

Sie wollen (wie ich denke, ist offensichtlich) - um überschriebene Namen in Dateinamen-Variablen zu erhalten...

Damit Init() richtig funktioniert, muss es nach der Konstruktion des Objekts aufgerufen werden.

Oder nicht?

Ich denke, die VMT wird nur im endgültigen Code des Konstruktors initialisiert. Wenn also eine Methode im Konstruktor aufgerufen wird, wird die Methode des Variablentyps aufgerufen, nicht der Typ des zu konstruierenden Objekts.

Das sieht in etwa so aus.

Wenigstens das funktioniert:

void OnStart()
  {
   CO2=new CCO2;
   CO2.Init();
   Print(CO2.Name()," filename=",CO2.filename);
   delete CO2;
   
   H2O=new CH2O;
   H2O.Init();
   Print(H2O.Name()," filename=",H2O.filename);
   delete H2O;
  }

Zu MetaQuotes: Wenn ich es richtig verstanden habe, ist es besser, den Aufruf virtueller Funktionen in Konstruktoren gänzlich zu verbieten. An.

Oder damit sie richtig funktionieren. Was ich bezweifle.

 

Ich lerne gerade parametrische Konstrukteure kennen. Aber es scheint, dass in dem Beispiel

//+------------------------------------------------------------------+
//| класс для хранения фамилии и имени персонажа                     |
//+------------------------------------------------------------------+
class CPerson
  {
   string            m_first_name;     // имя 
   string            m_second_name;    // фамилия
public:
   //--- пустой конструктор по умолчанию
                     CPerson() {Print(__FUNCTION__);};
   //--- параметрический конструктор
                     CPerson(string full_name);
   //--- конструктор со списком инициализации
                     CPerson(string surname,string name): m_second_name(surname, m_first_name(name)) {};
   void PrintName(){PrintFormat("Name=%s Surname=%s",m_first_name,m_second_name);};
  };
Die Klammern in der hervorgehobenen Zeile sind falsch gesetzt.
 
Yedelkin:

Ich lerne gerade parametrische Konstrukteure kennen. Aber es scheint, dass in dem Beispiel

in der hervorgehobenen Zeile sind die Klammern falsch gesetzt.
Danke, wir werden es korrigieren.
 

Technischer Beitrag (Beginn einer kleinen Diskussion über Initialisierung, auch in Konstruktoren). Verschoben, damit es nicht unter den schweren Schritten der Neuankömmlinge verloren geht: https://www.mql5.com/ru/forum/58/page31#comment_66890

Изучаем и пишем вместе на MQL5
Изучаем и пишем вместе на MQL5
  • www.mql5.com
2) вывод всей возможной информации по инструментам, ордерам и др.
 

Eine Frage zur Initialisierung. In der Regel erfolgt die Initialisierung von String-Variablen und komplexen Objekten automatisch, "by default". Dadurch wird eine bestimmte Menge an Rechenleistung des Computers verschwendet (ich nenne es "Computertakt", entschuldigen Sie die laienhafte Ausdrucksweise).

Jetzt gibt es Initialisierungslisten, die es Ihnen ermöglichen, Variablen mit benutzerdefinierten Werten zu initialisieren. Gibt es einen Unterschied in der Initialisierungsgeschwindigkeit zwischen der automatischen Initialisierung und der Initialisierung mit einem benutzerdefinierten Wert? Mit anderen Worten: Erhöht sich die Anzahl der "Computeranschläge" bei der Verwendung von Initialisierungslisten (und benutzerdefinierten Werten) im Vergleich zur automatischen Initialisierung?

 
Yedelkin: Mit anderen Worten: Erhöht die Verwendung von Initialisierungslisten (und benutzerdefinierten Werten) die Anzahl der "Computerzyklen" im Vergleich zur automatischen Initialisierung?
Und wenn wir ein paar Taktzyklen einsparen, ist das ein signifikanter Gewinn? Zumal die Initialisierung nur einmal erfolgt und die Werte später noch zugewiesen werden müssen.
 
Valmars:
Und wenn wir ein paar Taktzyklen einsparen, wird das einen signifikanten Gewinn bringen? Zumal die Initialisierung einmalig erfolgt und die Werte später noch zugewiesen werden müssen.
Die Antwort liegt nicht in der Sache selbst. Für mich persönlich ist die Frage wichtig, weil ich die Technik verstehen möchte. Jeder einzelne Taktzyklus ist wichtig. Sonst gäbe es keine Frage. Wir wissen, wie man Teekannen nietet, ohne sich an die Regeln zu halten.
 
Yedelkin:
Das ist für mich persönlich eine wichtige Frage, denn ich möchte die Technik verstehen.

Mit dem richtigen Ansatz würde alles so sein. Initialisierungslisten sind eine Folge der Einführung von parametrischen Konstruktoren.

Schauen wir uns zwei Beispiele an:

class A
{
private:
   // конструктор по умолчанию недоступен
   A(){}
public:
   A(const double& value)
      : m_Value(value)
   {}
private:
   double m_Value;
}

class B
{
public:
   B()
   // т.к. коструктор А не имеет конструктора по умолчанию, единственный способ
   // использования класса -- инициализация в списке инициализации.
   // по-другому просто не должно скомпилиться
      : A(0)
   {
   }

private:
   A m_Value;
}

Das steht alles in den Kommentaren.

Beispiel 2:

class A
{
public:
   A()
   {
      Init(0);
   }
   
   A(const double& value)
   {
      Init(value);
   }
   
   void Init(double value)
   {
      // очень тяжелая функция
   }
};

class B
{
public:
   // вариант1, правильный
   B(const double& value)
      : m_Value(value)
   {
   }

/*
   // вариант2, неправильный
   B(const double& value)
   {
      m_Value.Init(value);
   }
*/

private:
   A m_Value;
};
In Variante 1 haben wir also 1 Aufruf von Init und in Variante 2 2 Aufrufe. Und da die "Gefällt mir"-Funktion sehr schwer ist, ist das Plus da.
 

TheXpert, herzlichen Dank! Ich werde es mir ansehen.

Ich habe indirekt aus Ihren Worten verstanden, dass es keinen Geschwindigkeitsunterschied zwischen der automatischen Initialisierung von Variablen des Typs " String, dynamisches Array und komplexes Objekt" und der Benutzerinitialisierung der gleichen Variablen gibt.

 
Yedelkin:

Ihren Worten habe ich indirekt entnommen, dass es keinen Geschwindigkeitsunterschied zwischen der automatischen Initialisierung von Variablen des Typs " String, dynamisches Array und komplexes Objekt" und der Benutzerinitialisierung der gleichen Variablen gibt.

Zeigen Sie mir ein Beispiel, damit es keine Verwirrung gibt, dann werde ich antworten.