2017-07-18 8 views
10

実際にこれについて多くのものがオンラインですが、もっと私はもっと混乱して読んでいます。私はCombinatoricsと呼ばれるコンポーネントを書いていますが、これは数学的確率のものです。私はそれを複雑にしたくないので、コードはかなり短くて簡単です。それは質問のために重要ではありません、デルファイのインターフェイスの参照カウントのメカニズム

//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)に割り当てることができます。これを正しくコーディングしているかどうかはわかりません。ユーザがcDispositionを選択して演算を行い

  1. ユーザがcDisposition(異なる値)を選択し、計算
  2. ユーザがcPermutationを選択して演算を行う処理を行い

Iは:と仮定しますいつもFEngineに取り組んでいます。 refカウントはどのようにゼロになるでしょうか?フォーム(およびコンポーネント)が破棄されると、ゼロになりますか?私が理解できないことをよく説明してくれることを願っています。 FEngineはプライベート変数であり、私は実行時に異なるクラス(Createを呼び出す)を援助します。フォームが破棄されたり、新しいクラスが割り当てられたりすると、refカウントは0になりますか?

ニック・ホッジは彼の本でそれをしたので、私は彼を当然信頼しますが、私が何をしているか知りたいので、上記のようにコード化しました。

+0

インタフェースオブジェクトにデストラクタを追加し、ブレークポイントを挿入するだけで何が起こるかを知ることができます。 –

+1

私はあなたが "delphiでのコーディング"のTEncryptionの例を参照していると思います;)私はちょうど本をチェックしたところで、あなたはTInterfacedObjectについて語ったときに章の真ん中にあなたの質問に対する答えを見つけるべきです! –

+0

@Sertacあなたが何を言っているのか知りません、私は今学んでいますので、質問するのが簡単だと思っていました –

答えて

8

最初に表示されるコードに基づいて、Updateが呼び出され、新しい実装者ICombinatorioが作成され、FEngineに割り当てられます。参照カウントは1になります。Updateが呼び出された次の時刻、ICombinatorioのインプリメンターの別の新しいインスタンスが作成され(参照カウントは1になります)、FEngineに割り当てられます。 FEngineが指す先の実装者インスタンスは、その参照カウントを減少させます。ゼロの場合は破棄されます。 (おそらくあなたのコードサンプルに基づいています)。コンポーネントのデストラクタが(所有しているフォームが破壊された場合)に呼び出されたときに

はまた、暗黙のインスタンスのクリーンアップコードは、あなたのサンプルに基づいて、参照カウントをデクリメントしますnilにFEngineを、セット(となります破壊される)。

コードサンプルに基づいて、コードが正しく動作することが期待されます。きれいにインスタンス化し、オブジェクトをインターフェイスしたICombinatorioを破棄します。

+0

Aaaaahオハイオ州、ので、私は新しいインスタンスをFEngineにおしゃべりするときに古いものは0(それは破壊されている)のrefを持っているし、新しいものは1に行く。 0にはなりませんでしたが、全体の合計があります。あなたはそれが0-1-0-1-0-1だと言いますが、0-1-2-3-4のようなもので、最後は0であると思いました。ありがとうございます –

+1

はい、それは正しいです。 –

+0

Super Daveありがとうございました –

関連する問題