我有一个在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?
...
答案 0 :(得分:3)
我认为您的主要问题与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字符串是一个有趣的混合体。虽然它们是作为引用实现的,但是copy-on-write使它们的行为类似于值类型。
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时,这将变得相关。
答案 1 :(得分:2)
首先,你并不需要指向对象的指针,因为对象本身已经是一个引用类型,你可以将对象引用转换为integer
(虽然NativeInt
可能是更好。)要使用它,你必须从变量中取出整数并将其强制转换为指针/对象类型,如下所示:
var
intref: NativeInt;
cell: TsplCellObject;
begin
intref := myvar;
cell := TsplCellObject(intref);
//do something with Cell here
end;