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

 
Georgiy Merts:

Nein. Es ist klar, dass in diesem Fall die Variable beim Verlassen des Blocks gelöscht werden muss.

Ich spreche von Objekten, die von new erstellt wurden:

Der C#-Standard spezifiziert: "Sowohl wertartige Objekte, wie z.B. Strukturen, als auch referenzartige Objekte, wie z.B. Klassen, werden automatisch zerstört, aber wertartige Objekte werden zerstört, wenn der Kontext, in dem sie enthalten sind, zerstört wird, während referenzartige Objekte vom Müllsammler auf unbestimmte Zeit zerstört werden, nachdem der letzte Verweis auf sie entfernt wurde."

Hier mag ich diese "unberechenbare Zeit" nicht. Obwohl ich sogar zugebe, dass der Müllsammler das Objekt viel effektiver löschen kann, als ich selbst das Objekt im Destruktor der Klasse, die es erstellt hat.

Da niemand mehr darauf verweist, wird das Objekt logischerweise bei der nächsten Müllabfuhr gelöscht. Die Zeit ist nicht vorhersehbar, obwohl Sie GC bitten können, sie sofort zu erstellen. Aber auch dies ist eine Bitte, kein Auftrag ))).

 
Georgiy Merts:

Ich will damit nicht sagen, dass der Müllsammler ein lebendes Objekt oder einen Zeiger löschen wird. Ich will damit sagen, dass sie es entfernen wird, wenn sie es will.

Sharp verfügt über eine Funktion zum Schutz des Objekts vor dem Löschen durch den Müllsammler.

https://docs.microsoft.com/ru-ru/dotnet/api/system.runtime.interopservices.gchandle.alloc?view=netcore-2.0

// for standalone object
public byte[] RawSerialize(object objAny)
{
int rawsize = Marshal.SizeOf(objAny);
byte[] m_obj = new byte[rawsize];

        GCHandle hObj = GCHandle.Alloc(m_obj, GCHandleType.Pinned);

        Marshal.StructureToPtr(objAny, hObj.AddrOfPinnedObject(), false);
        hObj.Free();

return (m_obj);
}
GCHandle.Alloc Method (System.Runtime.InteropServices)
GCHandle.Alloc Method (System.Runtime.InteropServices)
  • dotnet-bot
  • docs.microsoft.com
Выделяет дескриптор для указанного объекта.Allocates a handle for the specified object.
 
Alexey Navoykov:

Und jetzt versuchst du verzweifelt, dir Ausreden auszudenken, warum du nichts davon wusstest ;)

Es macht keinen Unterschied, ob sie es sofort oder erst Monate später eingeführt haben, denn sonst hätten Sie ja nichts davon gewusst.)

Ich habe Angst, vor Scham zu verbrennen, aber ich wusste nichts von & & bis vor kurzem, bis ich es irgendwo auf fxsaber sah. Ich würde sonst GetPointer verwenden.

Aber ich habe im September darauf geachtet, dass es keine Möglichkeit gibt, einige Operationen mit Objekten zu überladen, und damals habe ich versucht, dieses Problem selbst zu lösen, und einige Leute haben mir geschrieben, dass es diese Möglichkeit nicht gibt. Und jetzt stellt sich heraus, dass sie existiert, also frage ich mich, wann genau sie erschienen ist (und warum sie nicht in der Hilfe steht).

 
SemenTalonov:

Wahrscheinlich werden sie in die Richtung von C# gehen, wo "verwalteter Code" keine Zeiger hat und alles ein Objekt hat, sogar einfache Typen bool int double, etc.

Das wäre schön, aber es ist unwahrscheinlich, dass sie irgendetwas in dieser Richtung ändern werden, weil es eine komplette Änderung des Konzepts der Terminalsprache bedeutet, und solche Dinge werden selten gemacht.

SemenTalonow:

Genau nach IMHO ist es notwendig, nicht zu vergessen, womit man es genau zu tun hat (Objekt oder Zeiger darauf).

Um das nicht zu vergessen, müssen Sie zu Beginn entscheiden, wann Sie Objekte und wann Sie Zeiger verwenden (idealerweise nie Objekte und immer Zeiger).

Und es ist albern, jedes Mal extra Buchstaben dafür zu schreiben (vor allem, wenn man sich mit Klammern abmüht).

Außerdem wird in diesem Fall die von Ihnen beschriebene Zuweisungsoperation nicht in Bezug auf ein Objekt, sondern auf sein Nicht-Objekt-Feld verwendet, was im Prinzip die Wahrscheinlichkeit eines Fehlers ausschließt (der Zeigertyp spielt bei einer solchen Operation keine Rolle).

 
Ilya Malev:

Um das nicht zu vergessen, müssen Sie zu Beginn genau entscheiden, wann Sie Objekte und wann Sie Zeiger verwenden (im Idealfall - nie Objekte und immer Zeiger).

Wenn man nach langer Zeit (ein oder zwei Jahre) seinen eigenen Code öffnet und sich schimpft, dass man an den "heiklen" Stellen keine Kommentare hinterlassen hat, oder wenn man Objekte nicht von Zeigern unterscheiden kann, ist das wie ein Totalverlust. Ich bin auch nicht der Meinung, dass wir die Verwendung von Autoobjekten ablehnen sollten. Ihre Verwendung macht den Code kompakt und verringert die Sorge um das Schicksal des Objekts, wenn es veraltet ist. Außerdem bin ich mir sicher, dass die Lebensdauer eines solchen Objekts dem Compiler im Voraus bekannt ist und er daher einen optimierteren Code als im Falle der dynamischen Erstellung erstellen kann.

Ilya Malev:

Und es ist einfach dumm, dafür jedes Mal zusätzliche Buchstaben zu schreiben (vor allem, wenn man sich mit Klammern abmüht).

Außerdem wird in dem von Ihnen beschriebenen Fall die Zuweisungsoperation nicht relativ zu einem Objekt, sondern zu seinem Nicht-Objekt-Feld verwendet, was die Wahrscheinlichkeit eines Fehlers grundsätzlich ausschließt (der Zeigertyp spielt bei einer solchen Operation keine Rolle).

Dieser Unsinn kommt daher, dass es in MQL keine andere Möglichkeit gibt, den Zugriff auf ein Objekt durch einen Zeiger zu bezeichnen. In C/C++ wäre es natürlich noch lakonischer.

pA->iValue

Der Grund für das Fehlen des Pfeils ist wahrscheinlich derselbe wie bei dem ursprünglichen"*" (unbekannt). In Qt (und wahrscheinlich auch in VS) ersetzt der Editor automatisch '.' durch '->', wenn auf das Objekt über einen Zeiger zugegriffen wird, d.h. es ist überhaupt kein zusätzlicher Aufwand nötig. Ich zweifle nicht daran, dass MQ dem Editor eine solche Funktionalität hinzufügen kann, wenn dies gewünscht wird. Wie sich herausstellt, ist in diesem Beispiel das einzige Anzeichen dafür, dass es sich um einen Zeiger handelt, das Präfix "p" im Namen. Und das auch nur, weil ich es nicht vergessen habe. Wenn alle so "taktvoll" sind, ist das in Ordnung))

D.h. potentiell gefährliche Codefragmente sollten explizit gekennzeichnet werden. Man muss sich nicht an sie erinnern, man muss sie sehen. Die Notwendigkeit einer solchen "Formalisierung der Beziehungen" zu den Objekten würde bei komplizierteren Beispielen als den oben genannten deutlicher werden. Zum Beispiel, wenn ein Klassenmitglied selbst ein Zeiger auf etwas ist.

Durch die einheitliche Behandlung vonPOINTER_AUTOMATIC undPOINTER_DYNAMIC wird der irreführende Eindruck erweckt, dass diese Arten von Zeigern ähnlich sind. Tatsächlich handelt es sich aber um unterschiedliche Entitäten, die eine unterschiedliche Behandlung erfordern.Dies ist das Hauptthema dieses Zweigs.Die offensichtlichste ist natürlich: währendPOINTER_AUTOMATIC immer auf ein reales Objekt zeigt,kann POINTER_DYNAMIC auch leer sein.

Und ich erinnere Sie nur an die verschiedenen Varianten des Datenzugriffs (allerdings in C/C++, solange unsere Pfade übereinstimmen)

BetreiberSyntaxWiederaufladbarImplementiert inCBeispiel
Mitglied vom Typ TDefinition außerhalb der Klasse
Zugriff auf ein Array-Elementa[b]JaJaRT::operator[](Sb);
k.A.
Indirekte Referenz ("Objekt, auf dasa zeigt")*aJaJaRT::operator*();R-Operator*(Ta);
Referenz ("Adressea")& aJaJaR-OperatorT::operator&();R-Operator&(Ta);
Verweis auf ein Element der Struktur ("das Element b des Objekts, auf dasa zeigt")a-> bJaJaR*T::operator->();[Anmerkung 5]
K.A.
Verweis auf ein Mitglied einer Struktur ("b Mitglied von Objekta")a. bNeinJak.A.
Mitglied, auf das b zeigt, in einem Objekt, auf dasa zeigt[Anmerkung 6]a->*bJaNeinR operatorT::operator->*(Sb);R-Operator->*(Ta, Sb);
Das Element, auf das b im Objekta zeigta.*bNeinNeinK.A.
 
SemenTalonov:

Nun, das Offensichtlichste ist natürlich: WennPOINTER_AUTOMATIC immer auf ein reales Objekt zeigt,kann auch POINTER_DYNAMIC leer sein.

Wenn schon das "Offensichtlichste" falsch ist, lohnt es sich dann, alles andere ernsthaft zu prüfen und zu beantworten?

POINTER_AUTOMATIC ist nicht der Typ der Variablen, sondern ihr Status. Im nächsten Moment kann der Status ganz anders sein. Einschließlich POINTER_INVALID, versteht sich.
 
Ilya Malev:

Wenn das "Offensichtlichste" bereits falsch ist, lohnt es sich dann, alles andere ernsthaft in Betracht zu ziehen und darauf zu reagieren?

Ich bitte um Klärung dieser Frage, wenn möglich

 
Ilya Malev:
POINTER_AUTOMATIC ist nicht der Typ einer Variablen, sondern ihr Status. Im nächsten Moment kann der Status ganz anders sein

Sicherlich nicht ein Typ. Sie meinen, dass das Auto-Objekt zu einem Zeiger mit dem StatusPOINTER_DYNAMIC wird, zum Beispiel? Gemeint ist derStatusPOINTER_INVALID bei der Deklaration z.B. eines Zeigers.

 
SemenTalonov:

Ich würde dies gerne klären, wenn möglich.

Es ist nur so, dass es in MCL offensichtlich nicht dasselbe ist wie in C++. Hier ist ein Zeiger kein separater Datentyp, sondern beides sind Objekte, und eine Variable enthält ihren Handle. Eine Variable hat eine versteckte Konstanteneigenschaft (wenn sie ohne * deklariert wird), aber das macht sie nicht grundsätzlich zu einer Variablen eines anderen Typs, sondern verbietet nur, ihr einen anderen Handle zuzuweisen.

 

Das heißt, erklären Sie

   A* const b=new A;

Und Sie werden genau das gleiche "Auto-Objekt" haben, nur dass Sie es selbst löschen werden

Grund der Beschwerde: