我一直给人的印象是,Delphi中的对象实际上是对内存位置的引用,而我想象这些对象又被存储为指针变量。

现在,我想从一个对象中创建一个TValue。考虑一下:

TValue.Make(AObject, TypeInfo(TMyObject), val);

其中val: TValue。这行不通。实际上,val的后续使用将导致访问冲突。但是,如果我们使用address-of运算符,如下所示:
TValue.Make(@AObject, TypeInfo(TMyObject), val);

一切都很好。对我来说,这是出乎意料的,因为我认为AObject实际上是(在幕后)一个指针。我是对的还是对TValue.Make方法的怪癖?有人可以启发我吗?

最佳答案

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;
  • 位置@I以及O(引用)的位置在堆栈中。
  • 另一方面,@ O的位置在堆上。

  • 通常,这无关紧要,因为编译器知道何时取消引用以及何时不引用。

    TValue.Make的情况下,该函数使用一个指针。
  • 当您指定Make(O...时,编译器将强制将引用强制转换为指针(指向堆栈)。
  • 当您指定Make(@O...时,编译器将首先取消引用,然后创建一个指向堆上位置的指针。

  • 因此,在这种情况下,您必须给编译器一个提示,因为它不知道TValue.Make希望使用哪种指针。

    10-07 19:45
    查看更多