2

レコードを定義すると、そのレコードのインスタンスを定数レコードとして定義できます

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

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

Tunitがクラスで、meterがクラスのインスタンスであるが、関連するフィールドを他のコードで変更できない(特定の)インスタンスである場合、同様のことを行う必要があります。これを達成する方法がわかりません。何かアイデアはありますか?

4

3 に答える 3

4

必要に応じて、同様のことを実現する方法が 2 つあります。

最初の方法では、ユニットの初期化手順 (対応するファイナライズ手順でインスタンスを解放することを忘れないでください) でクラスのインスタンスを初期化するか、アクセサー ユニット関数を使用して最初のアクセスでインスタンスを初期化します。

a)

  interface

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

   :

  implementation

   :

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

  finalization
    FreeAndNIL(metre);

  end.

注: クラスが単にデータのコンテナーである場合は、質問に表示されるように、ファイナライズの Free'ing を省略することを検討できます。技術的にはメモリ リークですが、インスタンスで使用されるメモリは実際には何もリークしません。アプリ プロセスが終了すると回収されます。プロジェクト内の他のファイナライズ コードが解放された後にメーター インスタンスにアクセスすると、ファイナライズで解放すると問題が発生する可能性があります。

また、いわゆる「シングルトン」クラスを使用しないように注意してください。このような単純なケースでは、複雑さとオーバーヘッドが追加され、利点はありません。

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.

この場合にも、ファイナライズのオプション性に関する同じ観察事項が適用されます。

また、パフォーマンスが重要な問題であり、このアクセサー関数が頻繁に使用される可能性が高い場合は、最初にファクトリ関数に初期化された関数ポインターを使用して、この領域を最適化するためのさらなる手順を実行できます。最初のアクセス時の単純な無条件アクセサー関数。

これを実現する 2 つ目の方法は、メンバー データを使用するのではなく、クラス関数を使用して、特別に派生したクラスから固定値を返すことです。その後、クラスをインスタンス化する必要はまったくなく、破棄について心配する必要もありません。Delphi 2010 がクラス関数だけでなくクラス変数もサポートするようになったかどうか、頭の中で思い出すことはできません。もしそうなら、それも答えかもしれません。ただし、Delphi 2010 を使用していない場合は、いずれにしても問題はありません。

次のようになります。

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

ただし、標準換算単位と関連する測定単位の機能を認識していますか? この質問の内容は、Delphi RTL の既存の側面によってすでに対応されているように見えるため、私が尋ねるだけです。

于 2009-12-21T02:46:09.133 に答える
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);
于 2009-12-21T03:47:16.617 に答える
0

定数オブジェクト値を作成することは技術的に可能ですが、その概念は通常のメモリ割り当て解除方法と互換性がなく、Delphi/ネイティブはそれをサポートしていません。

于 2009-12-22T06:40:07.530 に答える