8
3

More than 3 years have passed since last update.

[Delphi] class constructor と initialization は違うよという話

Last updated at Posted at 2020-12-17

initialization

initialization 節とは、Turbo Pascal の段階から載っていた unit の初期化節です。
ここに書くとアプリの起動時にメイン部より先に実行されます。

初期化節の例
unit Foo;

{中略}

initialization // 初期化節
  Bar;         // アプリの起動時に実行される

finalization // 終了処理節
  Baz;       // アプリの終了時に実行される

end.

class constructor

Delphi 2009 か 2010 のどちらか Delphi 2010 から搭載されている class constructor
(どこから載っているか特定できませんでした。恐らく 2009)
(コメントで Delphi 2010 からとご教授いただきました)

クラスコンストラクタの例
type
  TFoo = class
  private
    class constructor CreateClass; // ←これ
  end;

implementation

class constructor TFoo.CreateClass;
begin
  // なにか初期化
end;

クラス コンストラクタの呼び出しは、そのクラスが定義されているユニットの initialization セクションに、コンパイラが自動的に挿入します。

と DocWiki にあるように class constructor は基本的には initialization と同義です。
ある1点を除いては。

違い

initialization 節は必ず実行されるのに対して、class constructor は

クラスが使用されている場合にのみ実行される

という事です。

DocWiki にも

コンパイラがアプリケーションのどこかで TBox が実際に使用されているかどうか確認し、使用されている場合は、クラス コンストラクタの呼び出しがユニットの initialization セクションに自動的に追加されます

とありました。

Delphi はスマートリンカが載っているので使われていないクラスは削除されてしまうという訳です。
なので、initialization と同じ感覚で使うと、あれれ!?初期化部分が動いてないぞ~!?となってしまいます。

問題になるコード

例えば下記のようなコードです。

失敗
uses
  System.Classes;

type
  TFoo = class(TPersistent)
  private
    class constructor CreateClass;
  end;

implementation

class constructor TFoo.CreateClass;
begin
  RegisterClass(TFoo); // クラスを登録する処理(実行されない)
end;

この場合、TFoo が TFoo の外部(他のユニットやinitializationなど)から呼ばれないと TFoo は削除されリンクされません。
TFoo.CreateClass で RegisterClass に TFoo を渡していてもそれは TFoo 内部の話なので誰かが使っているとは認識されません。

この場合は

成功
uses
  System.Classes;

type
  TFoo = class(TPersistent)
  end;

implementation

initialization
  RegisterClass(TFoo); // クラスを登録する処理(実行される)

と、initialization を使うのが正解です。
この場合 initialization から使われるため、TFoo もリンクされます。

最後に

同じような機能がある場合、きちんと差異を知っておかないとダメですね

8
3
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
3