。それは実際にTList<T>
のコンストラクタであり、そこからTObjectList<T>
が派生したクラスです。
TObjectList<T>
で宣言されたすべてのコンストラクタは、プロパティを初期化するために使用されるAOwnsObjects
というパラメータを受け入れます。そのコンストラクタをバイパスしているため、OwnsObjects
はデフォルトでFalse
になり、リストのメンバーは破棄されません。
OwnsObjects
を初期化するTObjectList<T>
のコンストラクタを呼び出す必要があります。例えば:
type
TDerivedGenericObjectList = class(TObjectList<TObject>)
public
constructor Create(AOwnsObjects: Boolean = True);
end;
constructor TDerivedGenericObjectList.Create(AOwnsObjects: Boolean);
begin
inherited Create(AOwnsObjects);
end;
または::だから
type
TDerivedGenericObjectList = class(TObjectList<TObject>)
public
constructor Create(AOwnsObjects: Boolean = True);
end;
constructor TDerivedGenericObjectList.Create(AOwnsObjects: Boolean);
begin
inherited;
end;
、あなたが疑問に思うかもしれません
{$APPTYPE CONSOLE}
uses
System.Generics.Collections;
type
TDerivedGenericObjectList = class(TObjectList<TObject>)
public
constructor Create;
end;
constructor TDerivedGenericObjectList.Create;
begin
inherited Create(True);
end;
var
List: TDerivedGenericObjectList;
begin
ReportMemoryLeaksOnShutdown := True;
List := TDerivedGenericObjectList.Create;
List.Add(TObject.Create);
List.Free;
end.
おそらく、より良い変形は、あなたのコンストラクタもAOwnsObjects
パラメータを提供させることであろう元のバージョンがのものではなくTList<T>
のコンストラクタを選んだ理由。さて、それをもっと詳しく見てみましょう。ここにあなたのコードは、再びです:inherited
がこのように使用されている
type
TDerivedGenericObjectList = class(TObjectList<TObject>)
public
constructor Create;
end;
constructor TDerivedGenericObjectList.Create;
begin
inherited;
end;
は、コンパイラはこの1とまったく同じシグネチャを持つコンストラクタを探します。彼らはすべてパラメータを持っているので、TObjectList<T>
で見つけることができません。それはTList<T>
にあるものを見つけることができます、そして、それはそれが使用するものです。
次のバリアントが漏れないコメントで言及したよう:
constructor TDerivedGenericObjectList.Create;
begin
inherited Create;
end;
この構文、裸inherited
とは対照的で、デフォルトのパラメータが置換されている場合に一致する方法を見つけるだろう。したがって、TObjectList<T>
の単一パラメータコンストラクタが呼び出されます。
documentationは、この情報を持っています
継承された予約語が多型の挙動を実装する際の特別な役割を果たしています。メソッド定義の後に識別子がある場合とない場合があります。
メンバーの名前が続く場合は、参照されているメンバーの検索が、囲むメソッドのクラスの直下の祖先で始まる点を除き、通常のメソッド呼び出しまたはプロパティまたはフィールドへの参照を表します。例えば、次の場合:
inherited Create(...);
は、定義されたメソッドの中で発生し、継承されたCreateを呼び出します。
継承されたメソッドの後に識別子がない場合、継承するメソッドと同じ名前を持つ継承されたメソッド、または同じメッセージの継承されたメッセージハンドラへのメッセージハンドラの場合はメッセージハンドラを参照します。この場合、inheritedは明示的なパラメーターを取りませんが、囲まれたメソッドが呼び出されたのと同じパラメーターを継承したメソッドに渡します。例:
inherited;
は、コンストラクタの実装で頻繁に発生します。これは子孫に渡されたものと同じパラメーターを持つ継承コンストラクターを呼び出します。
リファクタリングが役立ちます。 – smooty86
コードに欠陥があるため、漏れがあります。あなたのコードは見えません。いずれにしても、なぜサブクラス化するのか。 'TObjectList'を直接使うことができます。あなたがそれにメソッドを追加しない限り。 –
@DavidHeffernanコンストラクタと使い方を追加して質問を編集しました。そのコードは 'TObjectList'で漏れません。しかし、 'TMembers'宣言を' TMembers = class(TObjectList) 'に変更すると、上のコードはメモリリークを示しています。そして、はい、私はそれにメソッドを追加したいと思います。私がここに示しているのは、うまくいけば明確な質問のための単純な構成例です。 –
alondono