それが可能だ。必要なメソッド/オブジェクトを公開するインターフェースを作成します。
type
IStringList = interface
procedure Add(const s: string); // etc.
property StringList: TStringList read GetStringList; // etc.
end;
インターフェイスを実装し、実際にラップさせますTStringList
。
type
TStringListImpl = class(TInterfacedObject, IStringList)
private
FStringList: TStringList; // create in constructor, destroy in destructor
// implementation etc.
end;
次に、レコードを実装します。
type
TStringListRecord = record
private
FImpl: IStringList;
function GetImpl: IStringList; // creates TStringListImpl if FImpl is nil
// returns value of FImpl otherwise
public
procedure Add(const s: string); // forward to GetImpl.Add
property StringList: TStringList read GetStringList; // forward to
// GetImpl.StringList
// etc.
end;
レコード内にインターフェイスがあるという事実は、コンパイラが参照カウントを自動的に処理し、コピーが作成および破棄されるときに_AddRefと_Releaseを呼び出すことを意味するため、ライフタイム管理は自動的に行われます。これは、それ自体への参照が含まれない(サイクルを作成する)オブジェクトに対して機能します。参照カウントには、参照グラフのサイクルを乗り越えるためのさまざまなトリックが必要です。