2009-12-09 80 views
14

有關記錄德爾福一些問題:記錄在Delphi

  1. 作爲記錄幾乎像班,爲什麼不使用只類的,而不是記錄?
  2. 理論上講,當內存被一個變量聲明時,它被分配給一條記錄;但是,以及內存如何發佈後?
  3. 我可以理解指針的記錄到列表對象的實用程序,但與泛型容器(TList<T>),是否需要使用指針呢?如果沒有,如何刪除/釋放每個記錄到一個通用容器?如果我想刪除一個特定的記錄到一個通用容器中,該怎麼做?

回答

10

對於1和2:記錄是值類型,而類是引用類型。它們被分配到堆棧中,或直接分配到包含它們的任何較大變量的內存空間中,而不是通過指針,並在編譯器超出範圍時自動清除。

至於你的第三個問題,TList<TMyRecord>內部聲明array of TMyRecord的存儲空間。當列表被銷燬時,所有記錄將被清除。如果要刪除特定的一個,請使用Delete方法按索引刪除,或使用Remove方法查找和刪除。但請注意,由於它是一種值類型,因此您所做的每件事都將複製記錄,而不是複製對其的引用。

+0

謝謝惠勒先生,還有一個問題更多: 指向record = Class? – 2009-12-09 21:49:28

+1

不,指向記錄的指針=指向記錄的指針。一個對象(類實例)以多種方式與記錄不同。 – 2009-12-09 23:05:50

3

類和記錄之間還有一些其他的區別。類可以使用polymorphism,並公開接口。記錄不能實現析構函數(儘管從Delphi 2006開始,它們現在可以實現構造函數和方法)。

由於記錄中的第一個數據項與指向記錄本身的指針的相同地址點,記錄在將內存分割成更爲邏輯的結構中非常有用。這不是類的情況。

+0

另外,記錄支持操作符重載,在某些情況下可能會有用。 – 2009-12-16 00:47:49

19

記錄和類之間有很多不同之處;並且沒有「記錄指針」<>「Class」。每個人都有自己的優點和缺點;關於軟件開發的重要事情之一是理解這些,以便您可以更輕鬆地選擇最適合於給定情況的選項。

  1. 這個問題是基於一個錯誤的前提。記錄幾乎不像類,就像整數幾乎不像雙精度一樣。
    • 類必須始終動態實例化,而這是一種可能性,但不是記錄的要求。
    • 類的實例(我們稱之爲對象)總是通過引用傳遞,這意味着多段代碼將共享並在同一個實例上執行。這是要記住的重要事情,因爲您可能會無意中將對象修改爲副作用;雖然故意完成這是一個強大的功能。另一方面,記錄按價值傳遞;您需要明確指出是否通過引用傳遞它們。
    • 班級不像記錄那麼容易複製。當我說複製時,我的意思是複製源的單獨實例。 (根據上面的價值/參考評論,這應該是顯而易見的)。
    • 記錄通常與輸入文件非常吻合(因爲它們非常容易複製)。
    • 記錄可以與其他字段疊加(字段x /工會)
    • 這些是對記錄的某些情境益處的評論;相反,對於我不會詳細闡述的課程來說,情境益處也是如此。
  2. 也許最簡單的方法來理解這是對它有點迂迴。讓我們澄清一下;內存在其聲明時並不真正分配,當變量處於範圍內時分配內存,當內存超出範圍時釋放內存。所以對於一個局部變量,它就在例程開始之前分配,並在結束後立即釋放。對於類字段,它在創建對象時分配,並在銷燬時釋放。
  3. 同樣,也有優點和缺點...
    • 它可以是慢,需要比僅複製引用更多的內存來複制整個記錄(如仿製藥)。
    • 通過引用傳遞記錄(使用指針)是一種功能強大的技術,您可以輕鬆地讓其他內容修改記錄副本。如果沒有這個,你必須通過價值傳遞你的記錄(即複製它)接收更改後的記錄,並將它複製到你自己的結構中。
  4. 是類指針的記錄指針?一點都不。只有兩個區別:
    • 類支持多態繼承。
    • 類可以實現接口。
+0

感謝Marco提供有關變體記錄的註釋(使用...的情況x) – 2009-12-10 09:18:37

9

一個記錄的主要好處是,當你有一個大的「記錄的陣列」。這是通過在一個連續的RAM空間中爲所有記錄分配空間而創建的,這是非常快的。如果您使用「TClass數組」,則陣列中的每個對象都必須自行分配,這很慢。

爲了提高字符串和對象的速度,提高內存分配的速度已經有很多工作要做,但它決不會像用1個內存分配替換100,000個內存分配一樣快。

但是,如果您使用記錄數組,請不要在本地變量中複製記錄。這可能很容易殺死速度優勢。

3

1)爲了允許繼承和多態,類有一些開銷。記錄不允許它們,並且在某些情況下可能會更快,更簡單。與類不同,類總是分配在堆中並通過引用進行管理,記錄也可以分配到堆棧中,直接訪問並相互分配,而無需調用「分配」方法。 另外,記錄對於訪問具有給定結構的內存塊很有用,因爲它們的內存佈局正是您如何定義它的。類實例內存佈局由編譯器控制,並具有用於使對象工作的附加數據(即指向虛擬方法表的指針)。 2)除非使用New()或GetMem()動態分配記錄,否則記錄的內存由編譯器按照序數,浮點數或靜態數組的形式進行管理:全局變量內存在啓動時分配並在程序終止時釋放,並且局部變量在堆棧中被分配進入一個函數/過程/方法並且被釋放退出。在堆棧中分配/釋放內存的速度更快,因爲它不需要調用內存管理器,只需要很少的彙編指令即可更改堆棧寄存器。但請注意,在堆棧上分配大型結構可能會導致堆棧溢出,因爲最大堆棧大小是固定的並不是很大(請參閱鏈接器選項)。 如果記錄是類的字段,則在類被釋放時創建並釋放它們時分配它們。

3)泛型的優勢之一是消除低級指針管理的需求 - 但要注意內部運作。

相關問題