You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取泛型实例的Pointer指针?两种取指针方式为何不同?

泛型变量指针获取问题解答

示例Pascal代码

TTestClass = class
  content: Integer;
end;

TTest = class
  public
    class procedure TestProc<T: class>(obj: T);
end;

class procedure TTest.TestProc<T>(obj: T);
var
  p: Pointer;
begin
  p := Pointer(obj);
  p := @obj;
end;

问题解析与解答

两种指针获取方式的差异原因

  1. p := Pointer(obj)
    当泛型约束为<T: class>时,T属于引用类型,obj本质是一个存储对象实例地址的指针。直接将obj转换为Pointer,得到的是堆内存中对象实例的实际地址——也就是这个引用指向的真实数据所在位置。

  2. p := @obj
    @运算符的作用是获取变量自身的内存地址。obj作为函数参数,存储在栈内存中(对于引用类型,这个栈变量里存的是对象实例的地址),因此@obj得到的是栈上这个参数变量的地址,和它指向的对象实例地址完全是两个不同的内存位置。

移除<T: class>约束后的通用指针获取方案

当T可以是任意类型(值类型如Integer、自定义记录,或引用类型如类、接口)时,需根据需求选择对应的指针获取方式:

场景1:获取变量自身的内存地址

无论T是值类型还是引用类型,直接使用@obj或Addr(obj)即可,两者效果一致。返回的指针指向存储obj这个变量的内存位置:

  • 对于值类型,该地址指向栈上的变量副本;
  • 对于引用类型,该地址指向栈上存储对象引用的变量。

场景2:获取变量对应实际数据的地址

需要区分T的类型,结合RTTI实现通用逻辑:

uses
  System.Rtti;

class procedure TTest.TestProc<T>(obj: T);
var
  p: Pointer;
  ctx: TRttiContext;
  typeInfo: TRttiType;
begin
  typeInfo := ctx.GetType(TypeInfo(T));
  if typeInfo.IsInstance then // 处理引用类型(类、接口等)
    p := Pointer(obj)
  else // 处理值类型
    p := @obj;
end;

内容的提问来源于stack exchange,提问作者John John

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 19:58:27