2017-07-18 78 views
10

事實上,網上有很多關於此的東西,但更多的是我讀了更多的混淆我。我寫了一個名爲Combinatorics的組件,它執行一些數學概率的東西。代碼非常簡短,因爲我不想讓它變得複雜。我在這裏做一個小的預覽:Delphi界面引用計數機制

//Combinatorio.pas 
type 
ICombinatorio = interface 
    function getSoluzioni(): integer; //soluzioni means "Solutions" 
    function getFormula(): string; 
end; 

//ImplCombinatorio.pas 
type 

TCombinazioni = class(TInterfacedObject, ICombinatorio) 
    private 
    n, k: integer; 
    ripetizione: boolean; 
    function fattoriale(const x: integer): integer; 
    public 
    constructor Create(const n, k: integer; const ripetizione: boolean); 
    function getSoluzioni(): integer; 
    function getFormula(): string; 
end; 

TDisposizioni = class(TInterfacedObject, ICombinatorio) 
    private 
    n, k: integer; 
    ripetizione: boolean; 
    function fattoriale(const x: integer): integer; 
    public 
    constructor Create(const n, k: integer; const ripetizione: boolean); 
    function getSoluzioni(): integer; 
    function getFormula(): string; 
end; 

TPermutazioni = class(TInterfacedObject, ICombinatorio) 
    private 
    n: integer; 
    k: string; 
    ripetizione: boolean; 
    function fattoriale(const x: integer): integer; 
    public 
    constructor Create(const n: integer; const k: string; ripetizione: boolean); 
    function getSoluzioni(): integer; 
    function getFormula(): string; 
end; 

你不需要怎麼看函數和過程來實現,它不是對這個問題很重要(你可以很容易地想象他們做了什麼)。


這是我的第一個組件,我編譯和安裝它,它的工作原理。但我不明白的東西。

unit TCombinatorio; 

interface 

uses 
    System.SysUtils, System.Classes, Combinatorio, ImplCombinatorio; 

type 
cCombinatorio = (cNull = 0, cDisposition = 1, cPermutation = 2, cCombination = 3); 

type 
TCombinatorics = class(TComponent) 
strict private 
    { Private declarations } 
    Fn, Fk: integer; 
    FRep: boolean; 
    FType: cCombinatorio; 
    FEngine: ICombinatorio; 
    procedure Update; 
public 
    { Public declarations } 
    constructor Create(AOwner: TComponent); override; 
    function getSolution: integer; 
    function getFormula: string; 
published 
    property n: integer read Fn write Fn; 
    property k: integer read Fk write Fk; 
    property kind: cCombinatorio read FType write FType default cNull; 
    property repetitions: boolean read FRep write FRep; 
end; 

procedure Register; 

implementation 

procedure Register; 
begin 
RegisterComponents('RaffaeleComponents', [TCombinatorics]); 
end; 

{ TCombinatorics } 

constructor TCombinatorics.Create(AOwner: TComponent); 
begin 

inherited Create(AOwner); 
Fn := 0; 
Fk := 0; 
FType := cNull; 
repetitions := false; 

end; 

function TCombinatorics.getFormula: string; 
begin 
Update; 
Result := FEngine.getFormula; 
end; 

function TCombinatorics.getSolution: integer; 
begin 
Update; 
Result := FEngine.getSoluzioni; 
end; 

procedure TCombinatorics.Update; 
begin 

case FType of 
    cDisposition: 
    FEngine := TDisposizioni.Create(n, k, repetitions); 
    cPermutation: 
    FEngine := TPermutazioni.Create(n, '', repetitions); 
    cCombination: 
    FEngine := TCombinazioni.Create(n, k, repetitions); 
    cNull: 
    raise Exception.Create('You have to select a type.'); 
end; 

end; 

end. 

看看Update;程序。我已經創建了這個函數,因爲當用戶在組件(link)中刪除必須在對象檢查器(或代碼中)設置的形式時,需要在構造函數中使用3個重要參數。

由於FEngine: ICombinatorio因爲有ref計數機制,所以我可以最終沒有嘗試地給它賦一個類(TCombinazioni,TDisposizioni或TPermutazioni)。我不確定我是否已正確編碼。假設:

  1. 用戶選擇cDisposition和做了計算
  2. 用戶選擇cDisposition(不同的值),並做了計算
  3. 用戶選擇cPermutation和做了計算

我我總是在FEngine上工作。參考計數如何歸零?當表單(和組件)銷燬時它是否爲零?我希望我已經解釋了我不明白的東西。 FEngine是一個私有變量,我在運行時爲它分配不同的類(調用Create)。當表格破壞或分配新類時,ref計數是否爲0?

我編碼它就像上面,因爲尼克霍奇斯在他的書中做到了這一點,我當然相信他,但我想知道我做了什麼。

+0

您可以簡單地將析構函數添加到您的接口對象中,並將斷點放在發現的位置。 –

+1

我猜你指的是「在delphi中編碼」的TEncryption示例;)我剛剛檢查過這本書,你應該在本章中間找到關於TInterfacedObject的問題的答案! –

+0

@Sertac我不知道你在說什麼對不起,我現在在學習,所以我覺得這很容易問 –

回答

8

根據可以看到的代碼,第一次調用Update時,會創建一個ICombinatorio的新實現器並將其指定給FEngine;引用計數將爲1.在調用Update後,將創建另一個ICombinatorio實現器實例的新實例(其引用計數爲1)並分配給FEngineFEngine指向的前一個實現者實例將使其引用計數遞減;如果它是零,那麼它將被銷燬。 (它可能會基於你的代碼示例)。另外,當調用組件的析構函數時(當擁有窗體被銷燬時),隱式實例清理代碼將把FEngine設置爲零,這將減少引用計數(並根據您的示例,將被銷燬)。

因此,根據您的代碼示例,我希望您的代碼能正常工作;乾淨地instanciating和銷燬接口對象ICombinatorio

+0

Aaaaah ok,所以當我抨擊FEngine一個新的實例時,舊的實例的ref爲0(所以它被銷燬了)並且新的實例化爲1.我認爲參考沒有去0但有一個總數。你說它是0-1-0-1-0-1 ......但我認爲它就像0-1-2-3-4,然後是0(最後是毀滅)。謝謝 –

+1

是的,這是正確的。 –

+0

Super Dave謝謝 –