その宣言は100個のオブジェクトを作成するのではなく、何も役に立たないことを指す100個のオブジェクト参照の配列を提供するだけです。
オブジェクトの作成は2段階のプロセスです。最初のステップはメモリの割り当てです(コードも割り当てません)。2番目のステップはコンストラクター(Createメソッド)を呼び出してそのメモリを初期化し、追加のオブジェクトを作成するなどです。
割り当て部分はループなしで実行できますが、各インスタンスを初期化するにはコンストラクターを呼び出す必要があります。
多くのVCLクラスには、追加のコンストラクターがありません。彼らは何もしない空のコンストラクターを持っているだけです。その場合、呼び出す必要はありません。
たとえば、文字列リストの配列をフェッチするには、次のコードを使用して、この例から調整します。
type
TStringListArray = array of TStringList;v
var
Instances: array of Byte;
function GetStringLists(Number: Integer): TStringListArray;
var
i: Integer;
begin
// Allocate instance memory for all of them
SetLength(Instances, Number * TStringList.InstanceSize);
// Zero the memory.
FillChar(Instances[0], Length(Instances), 0);
// Allocate array for object references.
SetLength(Result, Number);
for i := 0 to High(Result) do
begin
// Store object reference.
Result[i] := @Instances[i * TStringList.InstanceSize];
// Set the right class.
PPointer(Result[i])^ := TStringList;
// Call the constructor.
Result[i].Create;
end;
end;
そして、100個の文字列リストの配列を取得するには:
var
x: TStringListArray;
begin
x := GetStringLists(100);
したがって、この手順を使用すると、無視できる時間を節約でき、理論的にはメモリ効率が高くなります(断片化が少なくなります)が、ループが必要になります。簡単な解決法はない。