为什么TValue.Make需要指向对象引用的指针?

con*_*tor 8 delphi pointers object

我一直在Delphi的对象实际上引用的内存位置,这反过来我想象存储为指针变量的印象.

现在,我想从一个物体制作一个TValue.考虑一下:

TValue.Make(AObject, TypeInfo(TMyObject), val);
Run Code Online (Sandbox Code Playgroud)

哪里val: TValue.这不行.实际上,后续使用val会导致访问冲突.但是,如果我们使用address-of运算符,如下所示:

TValue.Make(@AObject, TypeInfo(TMyObject), val);
Run Code Online (Sandbox Code Playgroud)

一切都很好.对我来说,这是出乎意料的,因为我认为AObject(引擎盖下)实际上是一个指针.我错了,或者这是TValue.Make方法的怪癖?有人可以赐教吗?

Jen*_*off 9

procedure Foo;
var
  I: Integer; // value type
  O: TObject; // reference type
begin
  @I; // Get a pointer to I
  O := TObject.Create;
  @O; // Get a pointer to the memory "behind" the reference O
end;
Run Code Online (Sandbox Code Playgroud)
  • 位置@I以及O(引用)的位置在堆栈上.
  • 另一方面,@ O的位置在堆上.

通常这并不重要,因为编译器知道何时取消引用以及何时不引用.

TValue.Make函数的情况下采取指针.

  • 当您指定Make(O...编译器时,将强制转换为指针(指向堆栈)的引用.
  • 指定Make(@O...编译器时,首先取消引用,然后创建指向堆上位置的指针.

所以你必须在这种情况下给编译器一个提示,因为它不知道TValue.Make期望哪种指针.