Author: Tomas Rutkauskas
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!):
1 { ... }2 type3 TInterfaceStack = class4 private5 FList: TInterfacelist;
6 FCurrent: IInterface;
7 function GetTop: IInterface;
8 public9 constructor Create; virtual;
10 destructor Destroy; override;
11 procedure Push(aIntf: IInterface);
12 procedure Pop;
13 function IsEmpty: boolean;
14 property Top: IInterface read GetTop;
15 end;
16 17 { TInterfaceStack }18 19 constructor TInterfaceStack.Create;
20 begin21 inherited;
22 FList := TInterfacelist.Create;
23 FList.Capacity := 32;
24 end;
25 26 destructor TInterfaceStack.Destroy;
27 begin28 FList.Free;
29 inherited;
30 end;
31 32 function TInterfaceStack.GetTop: IInterface;
33 begin34 Result := FCurrent;
35 end;
36 37 function TInterfaceStack.IsEmpty: boolean;
38 begin39 Result := not Assigned(FCurrent);
40 end;
41 42 procedure TInterfaceStack.Pop;
43 begin44 if Flist.Count > 0 then45 begin46 FCurrent := FList[FList.count - 1];
47 FList.Delete(Flist.Count - 1);
48 end49 else50 FCurrent := nil;
51 end;
52 53 procedure TInterfaceStack.Push(aIntf: IInterface);
54 begin55 ifnot IsEmpty then56 FList.Add(FCurrent);
57 FCurrent := aIntf;
58 end;