首先:抱歉我的英语,希望能够解释我的需要。 还要考虑我是Delphi的新手。提前感谢所有试图帮助我的人。
我遇到这种情况:
全局变量
atd : array of ^TLabel
ADD动态标记到滚动框的一些过程
下面你会找到其中一个
procedure LabelINIT();
var L : Tlabel;
begin
....
while not DATASET.EOF do
begin
L := TLabel.Create(Self);
L.Parent := ScrollBox3;
L.Height := 13;
L.Width := 30;
L.Left := atd[DATASET.FIELDS[0].ASINTEGER].Left;
L.Top := atd[DATASET.FIELDS[0].ASINTEGER].Top + 3
...
atd[DATASET.FIELDS[0].ASINTEGER] := @L;
DATASET.NEXT;
end;
.....
end;
ATD应该存储最后插入的标签的地址......但实际上它存储了L变量的地址,因此在每个新循环中,ATD指向在while的开始时创建的新L。最糟糕的是,在程序之外我不能使用ATD中的值,因为它们引用了无效地址(L是局部变量)。
我想知道是否有办法直接指向创建的标签,而不是指向一个副本的变量。
换句话说,我想做的是:创建一个标签 - 找到自己的地址 - 指向它
我所做的是:创建一个LABEL,设置VARIABLE = LABEL,指向VAR
答案 0 :(得分:4)
让我们看一下您的代码:
procedure LabelINIT;
var
L: TLabel;
begin
....
atd[DATASET.FIELDS[0].ASINTEGER] := @L;
....
end;
现在,L
是一个局部变量。所以@L
是该局部变量的地址。当LabelINIT
返回时,该地址不再有效,因为变量生命已经结束。
您缺少的信息是TLabel
类型的变量实际上已经是指针。该变量是指向对象实例的指针。 Delphi中任何继承自TObject
的类型的变量都是指向对象实例的指针。
所以,解决方案很简单。将全局变量更改为:
atd: array of TLabel;
这是一个指向标签实例的指针数组。
将作业更改为atd
,如此:
atd[DATASET.FIELDS[0].ASINTEGER] := L;
虽然我已经将这些变量称为指针,但它们通常被称为Delphi中的引用。在适当的时候,我认为你会接受这个术语,但我在这个答案中使用指针来明确说明这些是什么。
类类型的变量实际上是引用对象的指针。因此,多个变量可以引用同一个对象。与其他指针一样,类类型变量可以保存值
nil
。但是,您不必显式取消引用类型变量来访问它指向的对象。例如,SomeObject.Size := 100
将值100
分配给Size
引用的对象的SomeObject
属性;你不会把它写成SomeObject^.Size := 100
。