インスタンスをコピーするには?

解決


son  2007-05-02 16:25:36  No: 25998

C/C++はかじったことがありますが、Delphiは全くの初心者です。
よろしくお願いいたします。

クラス型はそのインスタンスを示すアドレスと言うのはWebページ等
で理解できました。

C++だと、インスタンスの代入がコピーになるのですが、
インスタンスのコピーをするメソッド等はあるのでしょうか?
自分で定義したクラスの場合は自分で定義する必要があるのでしょうか?


Mr.XRAY  URL  2007-05-03 04:48:25  No: 25999

あまり意味を理解していないかも知れませんが,あるクラス型のインスタンスを
Createで生成すれば,他のそのクラスのオブジェクトには単に代入式( := )で
インスタンスもコピーされます.
これは,既にDelphiで用意されたT....というオブジェクトを変数として使用する
場合と同じです.

例         Labele1 : TLabel;
(これは  Label1:=TLabel.Create;  としなくても利用できる)

以下の例ではTMyClassのインスタンスである ValueGroup1を生成して,同じ
TMyClassのValueGropp2に代入しています.
ただし,独立してValueGruup1とValueGruup2を使用する場合は,どちらも
Createする必要があります.
そのような場合,インスタンスのコピーを行うには,Assignメソッドを
実装します(そのクラスのオブジェクト類を代入するコードを書く),

  TMyClass=class(TObject)
  protected
    FNum  : Integer;
    FMoji : String;
  public
    property Num : Integer read FNum write FNum;
    property Moji : String read FMoji write FMoji;
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
    ValueGroup1 : TMyClass;
    ValueGroup2 : TMyClass;
  end;

var
  Form1: TForm1;

implementation

uses DebugWndUnit;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
     ValueGroup1:=TMyClass.Create;

     ValueGroup1.Num:=100;
     ValueGroup1.Moji:='Delphi';

     ValueGroup2:=ValueGroup1;
     ShowMessage(IntToStr(ValueGroup2.Num)+'     '+ValueGroup2.Moji);
end;

//  Createして使い終わったら解放
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
     ValueGroup1.Free;
end;


Mr.XRAY  URL  2007-05-03 04:52:33  No: 26000

失礼しました !!

implementation部のusesは削除して下さい.
DebugWndUnitは私が,開発の際に使用しているものです.


son  2007-05-03 16:14:36  No: 26001

Mr.XRAY様、ご丁寧なご回答ありがとうございます。

当方のご説明がたりなかった部分があり、反省しております。
幾つかの数値とそのGetter/Setterを持つ、簡単なクラスTHoge
を作成し、それをバッファとして使おうと考えておりました。

Hoge1 := THoge.Create;
Hoge2 := THoge.Create;
:
:
Hoge1.setValue1(1.23);
Hoge1.setValue2(4.56);
:

Hoge2 := Hoge1;

Hoge1.setValue1(7.89);
Hoge1.setValue2(0.12);

ShowMessage(Hoge2.getValue1);
->ここで、7.89と表示されたのでWebを検索したところ、
「クラス型はインスタンスのポインタである。」
との記載がありましたので、コピーが作られないと理解
しました。

Javaでいうcloneメソッドみたいなものがあるかとおもった
のですが、自作クラスでは自分で実装する必要があるのです
ね。
勉強になりました。ありがとうございました。


Fusa  2007-05-03 20:56:12  No: 26002

Delphiの場合
Assignと表現します。

例えば例を挙げるとTFontのAssignはこのようになっています。

  TFont = class(TGraphicsObject)
…省略…
    procedure Assign(Source: TPersistent); override;

procedure TFont.Assign(Source: TPersistent);
begin
  if Source is TFont then
  begin
…省略…ここで全部のTFontのメンバーなどをコピーする処理
    Exit;
  end;
  inherited Assign(Source);
end;

宣言部でoverride指令は行ってください。これは
TFontや、ほとんどのVCLクラスはTPersistentを継承していまして
AssignはそのTPersistentで仮想宣言されているからです。

で、TFontを継承したTNeoFontを作りたい場合
次の用に実装するのがいいでしょう。

  TNeoFont = class(TFont)
…省略…
    FNewField: Integer;
    procedure Assign(Source: TPersistent); override;

procedure TNeoFont.Assign(Source: TPersistent);
begin
  if Source is TNeoFont then
  begin
    FNewField := TNeoFont(Source).FNewField;
  end;
  inherited Assign(Source);
end;

これで、
NeoFont1 := TNeoFont.Create;
NeoFont2 := TNeoFont.Create;
NeoFont1.Assign(NeoFont2);

NeoFont1.Free;
NeoFont2.Free;
とすることで、Fontインスタンスがコピーできます。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加