Mirror

Write a stack class for Interfaces (Views: 100)


Problem/Question/Abstract:

How to work with a stack of interfaces? Should I use TObjectStack or simply TStack?

Answer:

Using a storage class that uses elements typed as pointer or TObject is very risky with interfaces, since hard typecasts are needed, and they mess up the reference counting. So it is better to write your own stack class for interfaces, perhaps based on an internal TInterfaceList as storage mechanism. Something like this (untested!):

{ ... }
type
  TInterfaceStack = class
  private
    FList: TInterfacelist;
    FCurrent: IInterface;
    function GetTop: IInterface;
  public
    constructor Create; virtual;
    destructor Destroy; override;
    procedure Push(aIntf: IInterface);
    procedure Pop;
    function IsEmpty: boolean;
    property Top: IInterface read GetTop;
  end;

  { TInterfaceStack }

constructor TInterfaceStack.Create;
begin
  inherited;
  FList := TInterfacelist.Create;
  FList.Capacity := 32;
end;

destructor TInterfaceStack.Destroy;
begin
  FList.Free;
  inherited;
end;

function TInterfaceStack.GetTop: IInterface;
begin
  Result := FCurrent;
end;

function TInterfaceStack.IsEmpty: boolean;
begin
  Result := not Assigned(FCurrent);
end;

procedure TInterfaceStack.Pop;
begin
  if Flist.Count > 0 then
  begin
    FCurrent := FList[FList.count - 1];
    FList.Delete(Flist.Count - 1);
  end
  else
    FCurrent := nil;
end;

procedure TInterfaceStack.Push(aIntf: IInterface);
begin
  if not IsEmpty then
    FList.Add(FCurrent);
  FCurrent := aIntf;
end;

<< Back to main page