MQL5 Der Compiler unterscheidet nicht zwischen einer Klasse und einem Zeiger auf sie - Seite 3

 
SemenTalonov:

Bingo!

SemenTalonov2019.01.10 07:36POINTER_AUTOMATIC zu speichernund andersherum.

Nicht ganz ein Bingo. Bei einfachen Objekten funktioniert die Zuweisung mit dem Operator =. Es ist mit Sicherheit kein Fehler.

 
SemenTalonov:

...

SemenTalonov2019.01.10 07:36POINTER_AUTOMATIC in einen Zeiger vom TypPOINTER_DYNAMIC zu speichernund umgekehrt.

Nein. Wenn es nicht einen Zeiger auf Automatik zuweist, kopiert es ein Objekt - die Werte seiner Felder, aber nur bei einfachen Objekten.

 

Forum zum Thema Handel, automatisierte Handelssysteme und Strategietests

Der MQL5 Compiler unterscheidet nicht zwischen einer Klasse und einem Zeiger

SemenTalonov, 2019.01.10 04:18

class A
{
public:
    int iValue;
};
//......................
A m_A[2];

void OnStart()
{
A a;

    m_A[0] =a; 
    m_A[1] = new A();
}


Seit wann sind sie definiert (Frage an die Entwickler)

void A::operator =( const A& );
void A::operator =( const A* );

und wie funktionieren sie? Der folgende kompilierte Code sieht wahnhaft aus

    A* b = NULL;    
    m_A[1] = b;    


Und hier ist die Situation nicht eindeutig

A* m_A[2];

void OnStart()
{
A a;

    m_A[0] =a;  // Почему это работает?
    m_A[0] =&a; // Когда должно работать только это?
}
 
Dmitry Fedoseev:

Nicht gerade ein Bingo. Bei einfachen Objekten funktioniert die Zuweisung mit dem Operator =. Sicherlich kein Fehler.

Das ist richtig, das ist der wichtigste Punkt.

Ich persönlich bin der Meinung, dass man einen Zuweisungsoperator für Objekte nicht verwenden kann, wenn dieser Operator nicht explizit definiert ist, selbst wenn es sich um einfache Objekte handelt. Wir können uns immer noch irgendwie auf die Zuordnung von einfachen Strukturen einigen. Aber Klassen, in denen der Konstruktor notwendigerweise (zumindest implizit) aufgerufen wird, können nur durch explizit definierte Operatoren zugewiesen werden.

Meiner Meinung nach wurde dies getan, um Neulingen das Leben zu erleichtern.

 
Georgiy Merts:

Das ist richtig, das ist der wichtigste Punkt.

Ich persönlich bin der Meinung, dass man einen Zuweisungsoperator für Objekte nicht verwenden kann, wenn dieser Operator nicht explizit definiert ist, selbst wenn es sich um einfache Objekte handelt. Wir können uns irgendwie auf die Zuordnung von einfachen Strukturen einigen. Aber Klassen, deren Konstruktor notwendigerweise (zumindest implizit) aufgerufen wird, können nur mit explizit definierten Operatoren zugewiesen werden.

Meiner Meinung nach wurde dies getan, um Anfängern das Leben zu erleichtern.

Und komplexe sind praktisch - ohne sie kann man z. B. nicht MqlTradeRequest zurückgeben. Und bei Strukturen wird zwangsläufig auch ein Konstruktor aufgerufen.

 

Es gibt eine Theorie, dass MQL ein sehr abgespecktes C# ist. Es ist also verständlich, wie sich der MQL-Compiler in diesem Fall verhält. Schließlich werden die Klassen in C# immer im Heap platziert, daher:

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
class A
{
public:
    int iValue;
};
//......................
A m_A[2];

void OnStart()
{
    // Разместили A в куче, указатель на A передали в m_A[1]
    m_A[1] = new A();
    // Разместили A на стеке...
    A a;
    // А вот фиг вам! ля-ля-ля;) Там вам не тут. 'a' - класс и размещается в куче. Указатель на него передается внутреннему сборщику мусора
    // А раз так, то теперь он AUTOMATIC и к нему нельзя применить delete, т.к. внутренний сборщик мусора его удалит сам 
    
    // скопировали указатель a в массив
    m_A[0] = a;
}
//+------------------------------------------------------------------+

Nun wollen wir uns mit dem Array m_A befassen. Da m_A ein Array von Klassen ist und Klassen immer im Heap platziert werden, muss nicht angegeben werden, ob das Array m_A ein Array von Zeigern oder ein Array von Objekten selbst ist, da nur die erste Variante immer für Klassen funktioniert. Da m_A immer ein Array von Zeigern ist, muss MQL nicht angeben, ob es Referenztypen oder signifikante Typen speichert. Daraus folgt, dass A* m_A[2] == A m_A[2]. Amen.

 
Vasiliy Sokolov:

Es gibt eine Theorie, dass MQL ein sehr abgespecktes C# ist. Es ist also verständlich, wie sich der MQL-Compiler in diesem Fall verhält. Schließlich werden die Klassen in C# immer im Heap platziert, daher:

Nun wollen wir uns mit dem Array m_A befassen. Da m_A ein Array von Klassen ist und Klassen immer im Heap platziert werden, muss nicht angegeben werden, ob das Array m_A ein Array von Zeigern oder ein Array von Objekten selbst ist, da nur die erste Variante immer für Klassen funktioniert. Da m_A immer ein Array von Zeigern ist, muss MQL nicht angeben, ob es Referenztypen oder signifikante Typen speichert. Daraus folgt, dass A* m_A[2] == A m_A[2]. Amen.

Falsche Schlussfolgerung. m_A ist ein Array von Objekten, nicht von Zeigern. Und diese Objekte werden vollständig zerstört. Es ist nicht das neue A, das zerstört wird.

class A
{
public:
    int iValue;
    
  ~A()
  {
    Print(__FUNCSIG__);
  }
};
//......................
A m_A[2];

void OnStart()
{
A a;
A* b = new A;

    m_A[0] =a;  // копирование объекта, а не указателя
    m_A[1] = b; // копирование объекта, а не указателя
    
  // по выходу уничтожится три объекта
  delete b; // а так - четыре.
}
 
fxsaber:

Falsche Ausgabe. m_A ist ein Array von Objekten, nicht von Zeigern. Und diese Objekte werden vollständig zerstört. Es ist nicht das neue A, das zerstört wird.

Das ist ein gutes Beispiel. Nun, dann lassen Sie uns weiter darüber nachdenken.

 

Pfft)) Ich bin schockiert darüber.

A m_A[2];

void OnStart()
{
A a;
A* b = new A();

    printf("SizeOf 'a' object: %i SizeOf pointer 'b' to object: %i", sizeof(a), sizeof(b));
    
    a =b;
    b =a;
    
    m_A[0] = a;
    m_A[1] = b;
}
SizeOf 'a' object: 20 SizeOf pointer to 'b' object: 8
 
SemenTalonov:

Puh)) Ich bin wirklich schockiert darüber.

Was ist daran falsch? Im einen Fall ein Objekt, im anderen Fall ein Zeiger.