处理指向循环内创建的组件的指针

时间:2014-01-16 15:46:28

标签: delphi pointers

首先:抱歉我的英语,希望能够解释我的需要。 还要考虑我是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

1 个答案:

答案 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中的引用。在适当的时候,我认为你会接受这个术语,但我在这个答案中使用指针来明确说明这些是什么。

来自documentation

  

类类型的变量实际上是引用对象的指针。因此,多个变量可以引用同一个对象。与其他指针一样,类类型变量可以保存值nil。但是,您不必显式取消引用类型变量来访问它指向的对象。例如,SomeObject.Size := 100将值100分配给Size引用的对象的SomeObject属性;你不会把它写成SomeObject^.Size := 100