1

プロパティのリストを持つ基本的なクラスがあります。次に、子クラスを作成し、別のプロパティを追加します。コンポーネントをファイルに保存する必要があります。ただし、子コンポーネントを格納する代わりに、親が書き込まれます。

以下は、この問題を示す例です。

  MyComp1 = class(TComponent)
  strict private
    FS: string;
    FI: Integer;
  published
    property S: string read FS write FS;
    property I: Integer read FI write FI;
  end;

  MyComp2 = class(MyComp1)
  strict private
    FS2: string;
  published
    property S2: string read FS2 write FS2;
  end;

procedure SaveIt;
var
  MS: TMemoryStream;
  C1: MyComp1;
  C2: MyComp2;
begin
  MS := TMemoryStream.Create;
  try
    C1 := MyComp1.Create(nil);
    C1.S := 'Hallo, World!';
    C1.I := 100500;
    C2 := MyComp2(C1);
    C2.S2 := 'Second string';
    MS.WriteComponent(C2);
    MS.Position := 0;
    MS.SaveToFile('C:\test.dat');
  finally
    MS.Free;
  end;
end;

詳細:

時間とともに拡張されている機能があります。そこで、TComponent の基本クラス (MyComp1 と呼びましょう) とこの型の変数 (MyComp: MyComp1) を作成しました。機能を拡張したら、以前のバージョンから子孫クラスを作成します (MyComp2 = class(MyComp1)) 必要な新しいプロパティを追加し、その値を次のように割り当てます

MyComp2(MyComp).S2 := 'Second string';

次に、MyComp コンポーネントをファイルに保存する必要がありますが、子プロパティを使用します。こんな感じで作っています

MyComp := MyComp2.Create(nil)

ファイルに保存すると、MyComp1のプロパティしかありません

4

1 に答える 1

1

MyComp1のオブジェクトをインスタンス化していますが、それをに型キャストしているため、機能しませんMyComp2。これはメモリ内の実際のMyComp2オブジェクトではないためMyComp2、オブジェクトのプロパティに値を書き込むMyComp1ことは、MyComp1オブジェクトに属していないメモリにアクセスする無効な操作であり、せいぜいクラッシュし、最悪の場合はメモリを破損します。

この状況を処理する正しい方法は、オブジェクトインスタンスをMyComp2単独で作成することであり、まったく作成しないMyComp1ことです。 MyComp2からメンバーを継承するため、オブジェクトのプロパティにMyComp1アクセスできます。例:MyComp1MyComp2

procedure SaveIt;
var
  MS: TMemoryStream;
  Comp: MyComp2;
begin
  MS := TMemoryStream.Create;
  try
    Comp := MyComp2.Create(nil);
    try
      Comp.S := 'Hallo, World!';
      Comp.I := 100500;
      Comp.S2 := 'Second string';
      MS.WriteComponent(Comp);
    finally
      Comp.Free;
    end;
    MS.Position := 0;
    MS.SaveToFile('C:\test.dat');
  finally
    MS.Free;
  end;
end;
于 2012-12-16T01:18:07.883 に答える