學習 TList 類的實現 6

2021-09-05 18:44:17 字數 4235 閱讀 1235

實現 tmylist.add 函式.

tlist 中的 add 函式用到了乙個 grow 方法, 它的原理是元素越多就為以後準備更多記憶體, 我們這裡省略為預留 4 個元素的記憶體;

tlist 中的 add 函式還同時觸動了乙個 notify 方法, 這應該是為它們的子類準備的(估計是用它來激發乙個事件的), 也不要了.

function tmylist.add(item: pointer): integer;

begin

if fcount = fcapacity then setcapacity(fcapacity + 4);

flist^[fcount] := item;

result := fcount;

inc(fcount);

end;

再實現 tmylist.delete 過程.

同前, 把錯誤處理也簡化成乙個異常; 也省略了對 notify 方法的觸動.

其中用到了 system.move, 可以參考:

這裡有乙個問題是需要高度注意的: tlist 在刪除乙個元素(它的元素就是指標)時, 並沒有釋放指標指向的物件, 只是從列表開除;

如果要同時 free 掉物件, 應該使用 contnrs 單元下的 tobjectlist 類.

procedure tmylist.delete(index: integer);

begin

if (index < 0) or (index >= fcount) then

raise exception.createfmt('非法的 index:%d', [index]);

if index < fcount then

system.move(flist^[index + 1], flist^[index], (fcount - index) * sizeof(pointer));

dec(fcount);

end;

還要實現 tmylist.setcount 方法.

之前我沒有想到 count 屬性還是可寫的; 這可夠狠的, 譬如已經有 100 個元素, 如果讓 count := 1; 這一下就要刪除後面 99 個元素!

還有不理解的是: 譬如已經有 100 個元素, 如果讓 count := 200; 那後面的 100 個元素即便是填充了空字元, 用指標讀過來也不是物件啊? 覺得不妥. 不過暫時也這樣了.

procedure tmylist.setcount(const value: integer);

var i: integer;

begin

if (value < 0) or (value > maxlistsize) then

raise exception.createfmt('非法資料:%d', [value]);

if value > fcapacity then setcapacity(value);

if value > fcount then

fillchar(flist^[fcount], (value - fcount) * sizeof(pointer), 0)

else

for i := fcount - 1 downto value do

delete(i);

fcount := value;

end;

還有乙個 tmylist.clear 方法.

因為不用考慮列表中物件釋放的問題, 這個就簡單多了.

procedure tmylist.clear;

begin

setcount(0);

setcapacity(0);

end;

至此, 已經宣告的方法都實現了, 這個 tmylist 類也該能湊合使用了.

原始碼如下:

unit mylist;

inte***ce

uses sysutils;

const

maxlistsize = maxint div 16;

type

ppointerlist = ^tpointerlist;

tpointerlist = array[0..maxlistsize - 1] of pointer;

tmylist = class(tobject)

private

flist: ppointerlist;

fcount: integer;

fcapacity: integer;

procedure setcapacity(const value: integer);

procedure setcount(const value: integer);

public

destructor destroy; override;

function add(item: pointer): integer;

procedure clear;

procedure delete(index: integer);

property capacity: integer read fcapacity write setcapacity;

property count: integer read fcount write setcount;

property list: ppointerlist read flist;

end;

implementation

function tmylist.add(item: pointer): integer;

begin

if fcount = fcapacity then setcapacity(fcapacity + 4);

flist^[fcount] := item;

result := fcount;

inc(fcount);

end;

procedure tmylist.clear;

begin

setcount(0);

setcapacity(0);

end;

procedure tmylist.delete(index: integer);

begin

if (index < 0) or (index >= fcount) then

raise exception.createfmt('非法的 index:%d', [index]);

if index < fcount then

system.move(flist^[index+1], flist^[index], (fcount-index)* sizeof(pointer));

dec(fcount);

end;

destructor tmylist.destroy;

begin

clear;

inherited;

end;

procedure tmylist.setcapacity(const value: integer);

begin

if (value < fcount) or (value > maxlistsize) then

raise exception.createfmt('非法資料:%d', [value]);

if fcapacity <> value then

begin

reallocmem(flist, value * sizeof(pointer));

fcapacity := value;

end;

end;

procedure tmylist.setcount(const value: integer);

var i: integer;

begin

if (value < 0) or (value > maxlistsize) then

raise exception.createfmt('非法資料:%d', [value]);

if value > fcapacity then setcapacity(value);

if value > fcount then

fillchar(flist^[fcount], (value - fcount) * sizeof(pointer), 0)

else

for i := fcount - 1 downto value do

delete(i);

fcount := value;

end;

end.

學習 TList 類的實現 2

我原來以為 tlist 可能是乙個鍊錶,其實只是乙個陣列而已.你知道它包含著多大乙個陣列嗎?maxlistsize 個 maxlistsize 是 delphi 在 classes 單元定義的乙個常量 maxlistsize maxint div 16 也就是 134217727 這也是 tlist...

學習 TList 類的實現 7

總結目前 tmylist 已具備的功能 3 個方法 3 個屬性 add 新增 delete 刪除 clear 清空 count 元素總數 capacity 已存在的所有元素位置數 list 指向核心陣列的指標 唯讀 舉例測試如下 unit unit1 inte ce uses windows,mes...

ES6 類的實現原理

一段符合es6語法的 class a render class b extends a render 我在babel官網上輸入,檢視轉碼 長很多,從中找出關鍵點 宣告classclass a 檢視對應轉碼var a function 可以看出宣告乙個class就是通過建立並執行乙個匿名函式,在這個匿...