2014-01-16 14 views
0

首先:抱歉我的英文,希望能夠解釋我需要的東西。 另外考慮我是德爾福的新手。預先感謝所有想嘗試幫助我的人。處理循環內創建組件的指針

我有這種情況:

一個全局變量

atd : array of ^TLabel 

是新增動態標籤,一個滾動框的一些過程

下面你會發現他們中的一個

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指向在開始時刻創建的新L。最糟糕的是,當我不能使用ATD中的值時,因爲它們引用無效地址(L是本地變量)。

我想知道是否有辦法直接指向創建的標籤,而不是指向一個副本的變量。

在我想要做什麼其他的話來說就是:創建一個標籤 - 找到它自己的地址 - 指向它

我所做的是:創建標籤,設置一個變量= LABEL,POINT到變量

+4

從你的代碼中刪除'^'和'@'字符,你應該沒問題;-) – TLama

+0

謝謝,這可能是一個解決方案,但我會有一個TLabels的數組,這比一個指針數組,也考慮到atd可以存儲多達200個值,並且我還有其他3個相同類型的數組用於其他3個滾動條... – Bux

+2

@Bux編號'TLabel數組'是一個指針數組。 –

回答

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; 

雖然我已經提到了這些變量爲指針,它們更通常被稱爲德爾福發言引用。在適當的時候,我認爲你會來到這個術語,但我在這個答案中使用了指針來明確地說明這些東西是什麼。

documentation

類類型的的變量實際上是引用一個對象的指針。因此,多個變量可以指向同一個對象。像其他指針一樣,類類型變量可以保存值nil。但是,您不必顯式取消引用類型變量來訪問它指向的對象。例如,SomeObject.Size := 100將值100分配給由SomeObject引用的對象的Size屬性;你不會把它寫成SomeObject^.Size := 100