{$Mode delphi}
program Project1;
uses
Classes;
type
{ ITestInterface }
ITestInterface = interface
['{E634371B-7235-457C-A97C-2638F80F7680}']
//property methods
function GetList: TStringList;
//properties
property List : TStringList read GetList;
end;
{ TLeakyTestInterfaceImpl }
TLeakyTestInterfaceImpl = class(TInterfacedObject, ITestInterface)
strict private
FList : TStringList;
private
function GetList: TStringList;
public
property List : TStringList read GetList;
constructor Create;
destructor Destroy; override;
end;
{ TPluggedLeakTestInterfaceImpl }
TPluggedLeakTestInterfaceImpl = class(TInterfacedObject, ITestInterface)
strict private
FList : TStringList;
private
function GetList: TStringList;
public
property List : TStringList read GetList;
constructor Create;
destructor Destroy; override;
end;
{ TPluggedLeakTestInterfaceImpl }
function TPluggedLeakTestInterfaceImpl.GetList: TStringList;
begin
Result := FList;
end;
constructor TPluggedLeakTestInterfaceImpl.Create;
begin
FList := TStringList.Create;
end;
destructor TPluggedLeakTestInterfaceImpl.Destroy;
begin
//unlike the leaky example, this one properly frees the list
FList.Free;
inherited Destroy;
end;
{ TLeakyTestInterfaceImpl }
function TLeakyTestInterfaceImpl.GetList: TStringList;
begin
Result := FList;
end;
constructor TLeakyTestInterfaceImpl.Create;
begin
FList := TStringList.Create;
end;
destructor TLeakyTestInterfaceImpl.Destroy;
begin
//instead of freeing this object, our "list" will be leaked
inherited Destroy;
end;
////////////////////////////////////////////////////////////////////////////////
//EXAMPLE
//demonstration of using interfaces that will be freed automatically once
//all references go out of scope. we show that proper destructor code
//still needs to be used though, otherwise we will leak memory
////////////////////////////////////////////////////////////////////////////////
var
LLeaky,
LPluggedLeak : ITestInterface;
begin
//initialize both types of implementations
LLeaky := TLeakyTestInterfaceImpl.Create; //leaks List by not freeing in destructor
LPluggedLeak := TPluggedLeakTestInterfaceImpl.Create; //frees list in destructor
//after this "end" both interfaces classes will be freed because
//there are no references
end.