Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 将指针地址保存在变量中并访问它_Delphi_Pointers - Fatal编程技术网

Delphi 将指针地址保存在变量中并访问它

Delphi 将指针地址保存在变量中并访问它,delphi,pointers,Delphi,Pointers,我有一个在delphi中使用指针的初学者问题 我创建了一个对象,并将其地址保存在变量中。 但是我不知道如何使用这个变量访问对象。 这是我的密码: ... New(PSplObj); PSplObj^ := TsplCellObject.Create; PSplObj.description := sTeam; PSplObj.color := clRed; myvar := Integer(PSplObj); dispose

我有一个在delphi中使用指针的初学者问题

我创建了一个对象,并将其地址保存在变量中。 但是我不知道如何使用这个变量访问对象。 这是我的密码:

...
      New(PSplObj);
      PSplObj^ := TsplCellObject.Create;
      PSplObj.description := sTeam;
      PSplObj.color := clRed;
      myvar := Integer(PSplObj);
      dispose(PSplObj);

      // how to access the object throug the pointer in myvar?
...

首先,您不需要指向对象的指针,因为对象本身已经是引用类型,您可以将对象引用转换为
integer
(虽然
NativeInt
可能更好)。要使用它,您必须从变量中取出整数,并将其转换回指针/对象类型,像这样:

var
  intref: NativeInt;
  cell: TsplCellObject;
begin
  intref := myvar;
  cell := TsplCellObject(intref);
  //do something with Cell here
end;

首先,您不需要指向对象的指针,因为对象本身已经是引用类型,您可以将对象引用转换为
integer
(虽然
NativeInt
可能更好)。要使用它,您必须从变量中取出整数,并将其转换回指针/对象类型,像这样:

var
  intref: NativeInt;
  cell: TsplCellObject;
begin
  intref := myvar;
  cell := TsplCellObject(intref);
  //do something with Cell here
end;

我认为您的主要问题与什么是Delphi对象引用有关。考虑下面的人工例子:

type
  TMyRecord = record
    a, b, c: Integer;
  end;
  TMyClass = class
    a, b, c: Integer;
  end;
... 
var
  MyRecord: TMyRecord;
  MyObject: TMyObject;
...
MyObject := TMyObject.Create;
此时,我们有两个基本相同的结构化类型的实例。然而,Delphi呈现这些实例的方式是完全不同的。记录被称为值类型,对象是引用类型

指定给引用类型的变量时,将复制该值。例如:

MyRecord2.a := 1;
MyRecord1 := MyRecord2;
MyRecord1.a := 2;
Assert(MyRecord1.a<>MyRecord2.a);
MyObject2.a := 1;
MyObject1 := MyObject2;
MyObject1.a := 2;
Assert(MyObject1.a=MyObject2.a);
引用类型的一个特性是它们都是堆分配的,而值类型可以是堆或堆栈分配的

引用类型的示例包括类、接口、动态数组

Delphi字符串是一个有趣的混合体。尽管它们是作为引用实现的,但写时复制使它们的行为类似于值类型

Delphi的对象语法隐藏了这样一个事实:它们被实现为引用,即指针

Assert(SizeOf(MyRecord)=3*SizeOf(Integer));//=12
Assert(SizeOf(MyObject)=SizeOf(Pointer));//=4 (or 8 in Delphi 64)
所有这一切意味着你的代码是不必要的复杂。不需要为对象引用分配存储,因为对象变量已经是引用。你可以这样写:

//assign object reference to Variant
MyVariant := NativeInt(MyObject);

//extract object reference from Variant
NativeInt(MyObject) := MyVariant;

请注意,我使用的是
NativeInt
,因为它是一种整数类型,定义为至少与指针大小相同。当64位版本的Delphi出现时,这将变得相关。

我认为您的主要问题与什么是Delphi对象引用有关。考虑下面的人工例子:

type
  TMyRecord = record
    a, b, c: Integer;
  end;
  TMyClass = class
    a, b, c: Integer;
  end;
... 
var
  MyRecord: TMyRecord;
  MyObject: TMyObject;
...
MyObject := TMyObject.Create;
此时,我们有两个基本相同的结构化类型的实例。然而,Delphi呈现这些实例的方式是完全不同的。记录被称为值类型,对象是引用类型

指定给引用类型的变量时,将复制该值。例如:

MyRecord2.a := 1;
MyRecord1 := MyRecord2;
MyRecord1.a := 2;
Assert(MyRecord1.a<>MyRecord2.a);
MyObject2.a := 1;
MyObject1 := MyObject2;
MyObject1.a := 2;
Assert(MyObject1.a=MyObject2.a);
引用类型的一个特性是它们都是堆分配的,而值类型可以是堆或堆栈分配的

引用类型的示例包括类、接口、动态数组

Delphi字符串是一个有趣的混合体。尽管它们是作为引用实现的,但写时复制使它们的行为类似于值类型

Delphi的对象语法隐藏了这样一个事实:它们被实现为引用,即指针

Assert(SizeOf(MyRecord)=3*SizeOf(Integer));//=12
Assert(SizeOf(MyObject)=SizeOf(Pointer));//=4 (or 8 in Delphi 64)
所有这一切意味着你的代码是不必要的复杂。不需要为对象引用分配存储,因为对象变量已经是引用。你可以这样写:

//assign object reference to Variant
MyVariant := NativeInt(MyObject);

//extract object reference from Variant
NativeInt(MyObject) := MyVariant;

请注意,我使用的是
NativeInt
,因为它是一种整数类型,定义为至少与指针大小相同。当64位版本的Delphi出现时,这将变得相关。

第一个问题是您正在处理稍后尝试引用的对象。那肯定不行。实际上是在处理指向对象引用的指针。但是这里不需要显式的堆分配。这是一个非常非常糟糕的主意,不是一个好主意。这个问题可能是这个问题的一个扭曲的重复:为什么要这样做?还有“PSplObj^:=tsplcelobject.Create;”:我假设PSplObj是一个指针-如果是这样的话,那么在分配指针之前您正在延迟它?!你是说PSplObj:=tsplcelobject.Create吗?请看@mason的答案-我认为您需要重新考虑您的方法。第一个问题是您正在处理您稍后试图引用的对象。那肯定不行。实际上是在处理指向对象引用的指针。但是这里不需要显式的堆分配。这是一个非常非常糟糕的主意,不是一个好主意。这个问题可能是这个问题的一个扭曲的重复:为什么要这样做?还有“PSplObj^:=tsplcelobject.Create;”:我假设PSplObj是一个指针-如果是这样的话,那么在分配指针之前您正在延迟它?!你是说PSplObj:=tsplcelobject.Create吗?见@mason的答案-我认为你需要重新思考你的方法。嗨,David,非常感谢你的解释。我发布的通知来自devExpress()-因此我确信这是一个“好的”^^嗨,大卫,非常感谢你的解释。我发布的appreach是来自devExpress()-因此我确信它是一个“好的”^^