Zitat von
leddl:
@malo:
Bei ner Add-Methode mußt du einfach nur an das Array ein neues Element anhängen...
Genau DAS sollte man nicht machen.
Wenn es eine array-basierte Liste sein soll sollte man sie stufenweise vergrößern.
Eine Vergrößerung auf 172% der alten Größe hat sich als bester Allroundwert gezeigt. Bei kleinen Datenmengen wäre es möglich den ersten Sprung relativ großzügig ausfallen zu lassen, dadurch würde man sich vielleicht kleine weitere Kopiererei antun müssen.
Außerdem verstehe ich diese Liste von "Operatoren" nicht ganz...
Eine Liste von Tokens könnte, um es ganz plain & easy zu machen, so aussehen:
Delphi-Quellcode:
type
TToken = class
// was immer du damit machen willst ;-)
end;
TTokenClass = class of TToken;
Delphi-Quellcode:
type
TTokenListInherited = class(TObjectList)
protected
function getItem(aIndex: Integer): TToken; virtual;
procedure setItem(aIndex: Integer; aToken: TToken); virtual;
public
function Add(aToken: TToken): Integer; virtual;
function Remove(aToken: TToken): Integer; virtual;
function IndexOf(aToken: TToken): Integer; virtual;
function FindInstanceOf(aClass: TTokenClass;
aExact: Boolean = True;
aStartAt: Integer = 0): Integer; virtual;
procedure Insert(aIndex: Integer; aToken: TToken); virtual;
function First: TToken; virtual;
function Last: TToken; virtual;
property Items[Index: Integer]: TToken read getItem write setItem; default;
end;
implementation
{ TTokenListInherited }
function TTokenListInherited.Add(aToken: TToken): Integer;
begin
Result := inherited Add(aToken);
end;
function TTokenListInherited.FindInstanceOf(aClass: TTokenClass; aExact: Boolean;
aStartAt: Integer): Integer;
begin
Result := FindInstanceOf(aClass, aExact, aStartAt);
end;
function TTokenListInherited.First: TToken;
begin
Result := inherited First() as TToken;
end;
function TTokenListInherited.getItem(aIndex: Integer): TToken;
begin
Result := inherited GetItem(aIndex) as TToken;
end;
function TTokenListInherited.IndexOf(aToken: TToken): Integer;
begin
Result := inherited IndexOf(aToken);
end;
procedure TTokenListInherited.Insert(aIndex: Integer; aToken: TToken);
begin
inherited Insert(aIndex, aToken);
end;
function TTokenListInherited.Last: TToken;
begin
Result := inherited Last() as TToken;
end;
function TTokenListInherited.Remove(aToken: TToken): Integer;
begin
Result := inherited Remove(aToken);
end;
procedure TTokenListInherited.setItem(aIndex: Integer; aToken: TToken);
begin
inherited setItem(aIndex, aToken);
end;
Da Tlist seine Methoden nicht virtual deklariert hat, ist es nicht möglich diese zu überschreiben um auf den Typen zu testen.
Es ist also möglich, die Liste auf TObjectList oder einen Vorfahren zu casten und einfach etwas anderes als einen Nachfahren von TToken reinzuwerfen.
Möglich wäre es also TObjectList zu verwenden anstatt davon abzuleiten.
Dadurch kannst du dir sicher sein, dass nur TToken Instanzen in die InnerList gelangen können.
Wie im oberen Beispiel ist keinerlei zusätzliche Logik nötig, da diese bereits von TList / TObjectList bereitgestellt wird.
Delphi-Quellcode:
type
TObjectListClass = class of TObjectList;
TTokenListNotInherited = class
private
fInnerList: TObjectList;
protected
property InnerList: TObjectList read fInnerList;
function getItem(aIndex: Integer): TToken; virtual;
procedure setItem(aIndex: Integer; aToken: TToken); virtual;
public
function Add(aToken: TToken): Integer; virtual;
function Remove(aToken: TToken): Integer; virtual;
function IndexOf(aToken: TToken): Integer; virtual;
function FindInstanceOf(aClass: TTokenClass;
aExact: Boolean = True;
aStartAt: Integer = 0): Integer; virtual;
procedure Insert(aIndex: Integer; aToken: TToken); virtual;
function First: TToken; virtual;
function Last: TToken; virtual;
property Items[Index: Integer]: TToken read getItem write setItem; default;
procedure Clear; virtual;
constructor Create(); overload;virtual;
constructor Create(aListClass :TObjectListClass); overload;virtual;
end;
implementation
{ TTokenListNotInherited }
constructor TTokenListNotInherited.Create;
begin
fInnerList := TObjectList.Create(True);
end;
constructor TTokenListNotInherited.Create(aListClass :TObjectListClass);
begin
fInnerList := aListClass.Create(True);
end;
function TTokenListNotInherited.Add(aToken: TToken): Integer;
begin
Result := InnerList.Add(aToken);
end;
procedure TTokenListNotInherited.Clear;
begin
InnerList.Clear();
end;
function TTokenListNotInherited.FindInstanceOf(aClass: TTokenClass; aExact: Boolean;
aStartAt: Integer): Integer;
begin
Result := InnerList.FindInstanceOf(aClass, aExact, aStartAt);
end;
function TTokenListNotInherited.First: TToken;
begin
Result := InnerList.First() as TToken;
end;
function TTokenListNotInherited.getItem(aIndex: Integer): TToken;
begin
Result := InnerList[aIndex] as TToken;
end;
function TTokenListNotInherited.IndexOf(aToken: TToken): Integer;
begin
Result := InnerList.IndexOf(aToken);
end;
procedure TTokenListNotInherited.Insert(aIndex: Integer; aToken: TToken);
begin
InnerList.Insert(aIndex, aToken);
end;
function TTokenListNotInherited.Last: TToken;
begin
Result := InnerList.Last() as TToken;
end;
function TTokenListNotInherited.Remove(aToken: TToken): Integer;
begin
Result := InnerList.Remove(aToken);
end;
procedure TTokenListNotInherited.setItem(aIndex: Integer; aToken: TToken);
begin
InnerList[aIndex] := aToken;
end;
Der zweite Weg ist zwar gehörig hässlich aber hat nicht die Lücke des oberen.
btw: TList suckz