クラス作成と使用方法について

解決


クリリン  2005-06-29 12:17:36  No: 16001  IP: 192.*.*.*

お世話になります。

現在、テスト的にクラスを作ってみました。
こんな感じです。
----------------------------------------
type
  TTestClass = class(TObject)
  private
  public
    constructor Create(AOwner: TObject);
    destructor  Destroy; override;
  end;

  TForm1 = class(TForm)
<<中略>>
  end;

var
  Form1:  TForm1;
  TestClass:  TTestClass;

constructor TTestClass.Create(AOwner: TObject);
begin
  inherited Create;
end;

destructor TTestClass.Destroy;
begin
  inherited Destroy;
end;

----------------------------------------

これを使用するためにプロジェクトで以下のように使用しました。
----------------------------------------
begin
  TestClass.Create(Application);
  try
    Application.Initialize;
    Application.CreateForm(TForm1, Form1);
    Application.Run;
  finally
    TestClass.Free;
  end;
end.
----------------------------------------

コンパイルは通ったのですが、
実行時にクラスの例外エラーがでます。
どうしてなのでしょうか?

クラスの目的
外部変数をまとめたものをクラス化し、
アプリケーションの開始時に作成します。
アプリケーション終了後にこれらを削除しようとしています。

編集 削除
ななし  2005-06-29 13:31:16  No: 16002  IP: 192.*.*.*

プロジェクトではなく、上のユニット(TForm1のある方)で

initialization
  TestClass := TTestClass.Create(Application);

finalization
  TestClass.Free;

編集 削除
anone  2005-06-29 13:42:34  No: 16003  IP: 192.*.*.*

あと TComponent 派生クラス以外で Owner を設定してはいけません。
TObject 派生ならこの場合 Create; だけでコンストラクタはOK

編集 削除
クリリン  2005-06-29 13:58:04  No: 16004  IP: 192.*.*.*

どうも、お世話になりました。

プロジェクトの変更、ユニットの変更とも
教えられたとおりに変更するとうまくいきました。

でも、プロジェクトではなぜエラーになるのでしょうか?
Application.Initialize で initializationが実行されるんですよね。
で、実行されると finalization が最後に自動的に実行される
もののようですが、これって同じ処理ではないのですか?
以前DLL作ったときなんかでは同じようにして
うまくいっていたような気がするのですけど。

編集 削除
anone  2005-06-29 14:19:57  No: 16005  IP: 192.*.*.*

> プロジェクトではなぜエラーになるのでしょうか?

TestClass.Create(Application);

TestClass はまだインスタンスが作成されてないでしょ。ななしさんの

TestClass := TTestClass.Create(Application);

と比べてください。

コンスタラクタはクラス参照で使用します。

編集 削除
anone  2005-06-29 14:23:23  No: 16006  IP: 192.*.*.*

> Application.Initialize で initializationが実行されるんですよね。

これも違います。その前に実行されます。Application オブジェクトもそれで
作られているので Application.Initialize が実行できるのです。

編集 削除
クリリン  2005-06-29 14:37:05  No: 16007  IP: 192.*.*.*

あ、今気づきました。
以下のようにしなければいけなかったんです。
初歩的なミス(今まで気づかなかったです・・なさけない)してました。

begin
  TestClass := TTestClass.Create(Application);
  try
    Application.Initialize;
    Application.CreateForm(TForm1, Form1);
    Application.Run;
  finally
    TestClass.Free;
  end;
end.

このやり方でも正常に動作はするのですが、
でも、プロジェクト部では initialization や finalization を使うほうが
一般的なのでしょうか?
initialization や finalization はちょっとなじめなくて。
TStringList を使うときにはよく以下のようにするので

SLit := TStringList.Create;
try
finally
  SList.Free;
end;

こっちのほうが私にはなじみやすいのですけど

編集 削除
anone  2005-06-29 15:16:15  No: 16008  IP: 192.*.*.*

> プロジェクト部では initialization や finalization を使うほうが一般的なのでしょうか?

そのアプリが実行中、はじめから終わりまでずっと使いたい場合は initialization や finalization でやるべきです。

SLit := TStringList.Create;
try
finally
  SList.Free;
end;

こういうのは、一時的に使ってすぐ廃棄っていうときの定型ですね

編集 削除
クリリン  2005-06-29 15:43:45  No: 16009  IP: 192.*.*.*

勉強になりました。
みなさんどうもありがとうございました。

編集 削除
ん?  2005-06-30 01:44:47  No: 16010  IP: 192.*.*.*

> プロジェクト部では initialization や finalization を使うほうが一般的なのでしょうか?

自分は、あまりそういう使い方しません。
大概、メインフォームでインスタンスの生成・破棄を書いてしまいます。
あまり所有者不明の存在は作りたくない、というのが理由です。

編集 削除
えと  2005-06-30 03:41:44  No: 16011  IP: 192.*.*.*

> あまり所有者不明の存在は作りたくない、というのが理由です。

TObject からの派生クラスの所有者って意味不明。

編集 削除
みみ  2005-06-30 08:59:42  No: 16012  IP: 192.*.*.*

anoneさん、 
>あと TComponent 派生クラス以外で Owner を設定してはいけません。

これはどうしてでしょうか?
私は、TObjectから派生させた自前のクラスを作成し、例えばTForm等で
  Hoge := THoge.Create(Self);
の形でインスタンスを生成し、Hoge側からTFormに何らかの通知を行う際、
このSelfを使用しているのですが。

編集 削除
anone  2005-06-30 10:28:06  No: 16013  IP: 192.*.*.*

Owner によるインスタンスの自動管理は TComponent からの派生クラス以外は
機能しません。

TObject から派生したクラスのコンストラクタに Owner を設定しても、普通の
意味での Owner としての機能は果たしません。自分で private に FOwner とか
して、使う分には勝手ですけど。

編集 削除
みみ  2005-06-30 10:46:34  No: 16014  IP: 192.*.*.*

anoneさん、回答ありがとうございます。
>Owner によるインスタンスの自動管理は TComponent からの派生クラス以外は
>機能しません。
そういう意味でしたら、了解です。

編集 削除