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 もリンクされます。
最後に
同じような機能がある場合、きちんと差異を知っておかないとダメですね