Fragen zu OOP in MQL5 - Seite 44

 
Igor Makanu:

Da bin ich anderer Meinung:

Bitte aktualisieren Sie Ihr Wissen darüber, was "Zuweisungsoperator" und "Kopierkonstruktor" sind, wie sie sich unterscheiden und wann und wie sie (explizit und implizit) aufgerufen werden.
Im Code haben Sie die Rückgabe einer lokalen Variablen aus einer Funktion gelb hervorgehoben, was zum Aufruf des Standard-Kopierkonstruktors führt (nicht zu verwechseln mit dem Zuweisungsoperator).

Was ein "vollständiger Datentyp" ist, ist leider nicht ganz klar, ebenso wenig wie das, was Sie mit Ihrem Code zu beweisen versuchen...
Ich wiederhole:"DerStandard-MQL-Zuweisungsoperator gibt voidzurück;".

struct A{
   int x,y;
};

void OnStart(){
   A a, b;
   Print(typename(a = b));   // void
}
 
Koldun Zloy:

Falsch.

Definieren Sie einfach Ihren operator=, der dies zurückgibt, und sehen Sie den Unterschied.

Sie können den Unterschied sehen, wenn das Ergebnis der Zuordnung erneut zugewiesen wird.

Wenn ich operator= definiere, verfehle ich mein ursprüngliches Ziel, den Standard ::= aufzurufen

Das scheint eine unlösbare Frage zu sein.


Sergey Dzyublik:

Was "vollständiger Datentyp" ist, ist leider nicht ganz klar, ebenso wenig wie das, was Sie mit Ihrem Code beweisen wollten...

full ist voll - die Datenstruktur bleibt erhalten und es besteht keine Notwendigkeit, das Kopieren von Strukturen zu kontrollieren, wenn ich neue Felder hinzufüge

 
Igor Makanu:

Wenn ich den Operator = definiere, komme ich von meinem ursprünglichen Ziel ab, den Standard ::= aufzurufen

Brauchen Sie diese Art von Auftrag wirklich?

b = c = a;
 
Igor Makanu:

vollständig ist vollständig - die Datenstruktur bleibt erhalten und es besteht keine Notwendigkeit, das Kopieren von Strukturen zu kontrollieren, wenn neue Felder hinzugefügt werden

Nach Ihrer Terminologie könnte der Aufruf des Standard-Zuweisungsoperators dann einen "unvollständigen Datentyp" ergeben.
Der Fehler vom 2019.05.03 wurde nie behoben:https://www.mql5.com/ru/forum/1111/page2451#comment_11556395

 
Koldun Zloy:

Brauchen Sie wirklich einen solchen Auftrag?

rein theoretisch möchte ich wissen, ob es sich um eine "neue Entität" handelt und nicht um einen Operator =

Ich brauche es für den praktischen Gebrauch überhaupt nicht, ich habe kein Problem damit, es in 2 Betreiber zu stecken


Sergey Dzyublik:

Dann kann der Aufruf des Standard-Zuweisungsoperators nach Ihrer Terminologie einen "unvollständigen Datentyp" ergeben.
Der Fehler von 2019.05.03 wurde nie behoben:https://www.mql5.com/ru/forum/1111/page2451#comment_11556395

"Meine Terminologie" ist zu fragen, keine Beschwerden,

aber der Sinn der Verwendung des Standardoperators = ist, dass es bequem ist, nur die Felder in der Struktur zu beschreiben, und alles wird kopiert, einschließlich der Array-Dimensionen (obwohl nur mit zunehmenden Dimensionen - das Prinzip der Arbeit ist das gleiche wie in ArrayCopy() )


Nun, wenn es ein Fehler ist, muss es so weit sein.

 

die Frage ist rein theoretisch:

haben, möglicherweise in SB, einen solchen Konstruktoraufruf gesehen:

class A{
public:   
   A(){Print(__FUNCTION__);}
};

class B{
public:   
   A a1,a2;
   B():a1(),a2() { Print(__FUNCTION__); }   
};

wie würde sich dieser Code unterscheiden:

class A{
public:   
   A(){Print(__FUNCTION__);}
};

class B{
public:   
   A a1,a2;
   B() { Print(__FUNCTION__); }   
};

Ich habe es entpackt, ich sehe keinen Unterschied, dann ein bisschen genauer sein - was oder warum können wir einen erzwungenen Konstruktor Aufruf für a1 und a2 Objekte verwenden?

Worin besteht die "Bequemlichkeit" der ersten Option?

 
Igor Makanu:

die Frage ist rein theoretisch:

haben, möglicherweise in SB, einen solchen Konstruktoraufruf gesehen:

wie würde sich dieser Code unterscheiden:

Ich habe es entpackt, ich sehe keinen Unterschied, dann ein bisschen genauer sein - was oder warum können wir einen erzwungenen Konstruktor Aufruf für a1 und a2 Objekte verwenden?

Worin besteht die "Bequemlichkeit" der ersten Option?

Konstruktoren können Parameter haben und diese müssen irgendwie übergeben werden.

Das heißt, solange es keine Parameter gibt, gibt es keinen Unterschied, aber wenn Sie den Konstruktor A(int arg) verwenden, sieht die Sache anders aus

 
Maxim Kuznetsov:

Konstruktoren haben Parameter, und die müssen irgendwie übergeben werden

Solange es keine Parameter gibt, ist der Unterschied unbedeutend. Aber wenn Sie den Konstruktor A(int arg) haben, sieht es anders aus

Sie haben wahrscheinlich recht - es kommt auf den Zweck an.

Ich habe gerade in Schwierigkeiten wegen der ersten Variante, als ich 2 Konstruktoren der Klasse B verwenden wollte und doppelten Code in beiden Konstruktoren erhielt - ich entfernte sie, und alles, was ich bekam, war ein Teil des Codes, der in der ersten Variante war, und die Frage stellte sich, wo ich es sah und warum ich es so schrieb )))

 
Igor Makanu:

was gibt oder warum können die Konstruktoren der Objekte a1 und a2 gezwungen werden, zu verwenden?

Der korrekte Prozessname ist nicht "erzwungener Konstruktoraufruf a1 und a2", sondern Initialisierung von (nicht statischen) Klassenfeldern.
Obligatorisch in Fällen von:

- Verwendung konstanter Klassenfelder;
- das Fehlen eines Standardkonstruktors für die Klassenfelder;
- Fehlen einer anderen Art der Initialisierung von Objekten als durch den Aufruf des Konstruktors (z. B. wird der Zuweisungsoperator entfernt);
-...

 

Kann jemand erklären, warum diese Initialisierung der Felder besser ist als diese:

CArray::CArray(void) : m_step_resize(16),
                       m_data_total(0),
                       m_data_max(0),
                       m_sort_mode(-1)
  {
  }

ist besser als dies:

CArray::CArray(void)
  {
        m_step_resize=16;
        m_data_total=0;
        m_data_max=0;
        m_sort_mode=-1;
  }

Und was ist überhaupt der Sinn?