對David提出的答案進行了長時間評論,概述了我提取的解決方案。
以下編譯和工作。
首先像往常一樣創建記錄,但添加一個Free
過程來釋放任何基於堆的實例。
type
TMiniStack<T> = record
private
SP: Integer;
Items: array[0..StackSize - 1] of T;
function GetItem(index: Integer): T; inline;
public
procedure Free;
procedure Init; inline;
function Pop: T; inline;
procedure Push(const Item: T); inline;
....
end;
比創建靜態保持類,該類定義指向泛型類型的指針。
請注意,靜態類沒有任何數據成員,您甚至可以將其抽象以確保它不被實例化。
MiniStack<T> = class
public type
PStack = ^Stack;
Stack = TMiniStack<T>;
public
class function Create(StackDepth: integer = DefaultStackSize): PStack;
end;
的Create
是有點用詞不當,因爲它不會創建MiniStack<T>
,但TMiniStack<T>
。
創建函數的實現如下:
class function MiniStack<T>.Create(StackDepth: integer = DefaultStackSize): PStack;
begin
Result:= AllocMem(SizeOf(TMiniStack<T>) +
((StackDepth - DefaultStackSize) * SizeOf(T)));
end;
唯一剩下要做的就是要創造一個特定的pstack在使用任何環境中的PStack
的別名。
測試按預期工作。
type
PStack = MiniStack<Integer>.PStack;
procedure TMyTestObject.TestStack;
var
MyHeapStack: PStack;
begin
MyHeapStack:= MiniStack<Integer>.Create;
try
MyHeapStack.Push(100);
MyHeapStack.Push(101);
MyHeapStack.Push(102);
Assert.IsTrue(MyHeapStack.Pop = 102);
Assert.IsTrue(MyHeapStack.Pop = 101);
Assert.IsTrue(MyHeapStack.Pop = 100);
finally
MyHeapStack.Free;
end;
end;
最重要的事是,內聯(重要的ministack的速度(每個電話只有2或3的CPU指令))仍然有效,這個解決方案。
您可以在記錄中聲明'Type PT =^T;'並將其用作'var: m:TMiniStack .PT;':'m:= TMiniStack .Create;'。 –
2014-08-28 11:19:00
不,它不是,因爲這個問題沒有答:不提供答案和B:我已經知道如何使一個指針在泛型類型本身內進行操作。我正在向你提到的那個問一個具體的跟進問題。 – Johan 2014-08-28 11:20:05
@LURD,我對^ T不感興趣,我想要一個'^ TMiniStack'。 –
Johan
2014-08-28 11:21:05