2009-12-21 55 views
2

如果我定義了一條記錄,我可以將該記錄的一個實例定義爲常數記錄例如,常量類實例

Tunit = record 
    _name: string; 
    _scale: real; 
end; 

const metre: Tunit = 
    (_name: 'metre'; 
    _scale: 1.0; 
) 

我需要做同樣的事情,其中​​TUNIT是和儀表是類的實例,但它是一個(尤其是)實例,其相關的領域不能被其它代碼進行更改。 我看不出如何實現這一點。請有任何想法嗎?

+0

您可以使用編輯器中的101010按鈕將文本格式化爲代碼。 – itowlson 2009-12-21 01:29:05

+0

從來沒有見過這樣的按鈕!!?這是什麼? – user235720 2009-12-21 11:34:21

+0

這是編輯工具欄中的第5個按鈕。 – 2009-12-21 14:17:51

回答

4

有實現的東西兩種方式類似,根據您的需要:

第一種方式包括初始化類的一個實例單元初始化程序無論是在(記住要釋放的情況下在相應的定稿程序)或使用訪問單元功能初始化第一次訪問該實例:

一)

interface 

    var 
    metre : TUnit = NIL; // Can initialise a unit variable 

    : 

    implementation 

    : 

    initialization 
    metre := TUnit.Create(...); 

    finalization 
    FreeAndNIL(metre); 

    end. 

注意:如果您的CLAS s只是數據的一個容器,因爲它從你的問題出現,那麼你可能會考慮省略Free'ing的終結 - 雖然technicall是內存泄漏,但實際上並不會泄漏任何內容,因爲當您的應用程序使用的內存將被回收進程終止。如果您的項目中的其他終止代碼在free_d後訪問流量計實例,則在定稿中釋放可能會導致問題。

我也提醒你不要嘗試使用任何所謂的「單身」類。他們在這樣簡單的情況下增加了零利益的複雜性和開銷。

B)

interface 

    function Metre: TUnit; 

    implementation 

    var 
    _metre : TUnit = NIL; // Can initialise a unit variable 


    function Metre: TUnit; 
    begin 
    if NOT Assigned(_metre) then 
     _metre := TUnit.Create(...); 

    result := _metre; 
    end; 


    finalization 
    FreeAndNIL(metre); 

    end. 

w.r.t定稿的可選性的相同的觀察適用於這種情況下,也。

還要注意,如果性能是一個重要的關注點,並且這個訪問器函數可能會被大量使用,那麼您可以採取進一步的步驟來優化這個區域,使用初始化爲工廠函數的函數指針來替代自身第一次訪問時指向簡單的無條件訪問器函數的指針。

實現它的第二種方法是使用類函數從特定的派生類中返回固定值,而不是使用成員數據。那麼你根本就不需要實例化這個類,也不需要擔心處理它。如果Delphi 2010現在支持類變量和類功能,那麼我記不住頭腦 - 如果確實如此,那也可能是一個答案。但是,如果你不使用德爾福2010年,那麼這個問題將無濟於事。

它看起來有點像:

TMetre = class(TUnit) 
    class function Name: String; override; 
    class function Scale: Double; override; 
end; 

然而,我不知道......你知道標準轉換單元和測量功能關聯單位的?我只問,因爲這個問題的內容看起來可能已經被Delphi RTL的一個現有方面所照顧。

+0

非常感謝所有 - 非常有幫助。重新轉換,是的,我隱約意識到這一點,但我在這裏勾畫出本體論,而不是對單元到單元轉換本身特別感興趣 - 它們只是作爲本體論要求的一部分出現。 – user235720 2009-12-21 11:43:39

4

嘗試只讀屬性:

interface 
type 
    TUnit = class 
    private 
    _name: string; 
    _scale: real; 
    class function makeunit(aname: string; ascale: real): TUnit; 
    public 
    property name: string read _name; 
    property scale: real read _scale; 
    end; 

function metre: TUnit; 

implementation 

var 
    _metre : TUnit = nil; 

class function TUnit.makeunit(aname: string; ascale: real): Tunit; 
begin 
    Result._name := aname; 
    Result._scale := ascale; 
end; 

function Metre: TUnit; 
begin 
    if not Assigned(_metre) then 
    _metre := TUnit.makeunit('metre', 1.0); 
    result := _metre; 
end; 

finalization 
    FreeAndNIL(_metre); 
+0

謝謝 - 這似乎照顧了只讀要求 t – user235720 2009-12-21 14:11:06

0

雖然這在技術上是可能創造常量對象的值,這一概念將與正常的內存釋放方法不兼容,和Delphi /原生不支持它。