Warum benötigt TValue.Make einen Zeiger auf eine Objektreferenz?

8

Ich hatte schon immer den Eindruck, dass Objekte in Delphi tatsächlich Verweise auf Speicherorte sind, die wiederum, wie ich mir vorgestellt habe, als Zeigervariablen gespeichert wurden.

Nun möchte ich einen TValue von einem Objekt machen. Bedenken Sie Folgendes:

%Vor%

wo val: TValue . Dies wird nicht funktionieren. Tatsächlich führt die nachfolgende Verwendung von val zu einer Zugriffsverletzung. Wenn wir jedoch den address-of-Operator verwenden, wie folgt:

%Vor%

alles ist gut. Für mich war das unerwartet, da ich dachte, dass AObject (unter der Haube) tatsächlich ein Zeiger ist. Bin ich falsch oder ist das eine Eigenart mit der TValue.Make Methode? Könnte jemand bitte mich aufklären?

    
conciliator 07.11.2011, 10:07
quelle

3 Antworten

9
%Vor%
  • Die Position @I sowie die Position von O (der Referenz) befinden sich auf dem Stapel.
  • Der Ort @O befindet sich andererseits auf dem Heap.

Normalerweise spielt das keine Rolle, weil der Compiler weiß, wann dereferenziert werden soll und wann nicht.

Im Fall von TValue.Make nimmt die Funktion einen Zeiger.

  • Wenn Sie Make(O... angeben, wird der Compiler den Verweis auf einen Zeiger (der auf den Stapel verweist) hart werfen.
  • Wenn Sie Make(@O... angeben, wird der Compiler zuerst deneferenzieren und dann einen Zeiger auf den Speicherort auf dem Heap erstellen.

Sie müssen also dem Compiler in diesem Fall einen Hinweis geben, da er nicht weiß, welche Art von Pointer das TValue.Make erwartet.

    
Jens Mühlenhoff 07.11.2011, 12:27
quelle
2

Das ABuffer-Argument, das Sie an TValue.Make übergeben, ist der Zeiger auf den Wert, den Sie in TValue speichern möchten. Es spielt keine Rolle, ob der Typ selbst ein Zeigertyp ist oder nicht. Sie müssen also den Verweis auf AObject übergeben, auch wenn AObject selbst auch ein Zeiger ist.

In dem von Ihnen geposteten Beispiel würde ich lieber den TValue.From & lt; T & gt; Methode:

%Vor%

Wenn die Typinfo bei compiletime nicht bekannt ist, müssen Sie TValue.Make verwenden - andernfalls TValue.From & lt; T & gt; ist einfacher zu benutzen.

    
Stefan Glienke 30.05.2012 08:16
quelle
1

In Ihrem Beispiel ist AObject eine Referenz auf ein Objekt, nicht das Objekt selbst. Auf diese Weise deklarieren Sie den Objektverweis in Delphi im Gegensatz zu einer anderen Sprache, in der Sie dem Objekt explizit Referenz oder Zeiger hinzufügen müssen.

Also sollte AObject oder @AObject in Ihrem Fall genauso funktionieren, aber da TValue.Make() im ersten Parameter einen Zeiger auf einen Puffer verwendet, sollten Sie% angeben. co_de% oder Addr(AObject) für die Funktion.

    
TridenT 07.11.2011 10:22
quelle

Tags und Links