實現 tmylist.add 函式.
tlist 中的 add 函式用到了乙個 grow 方法, 它的原理是元素越多就為以後準備更多記憶體, 我們這裡省略為預留 4 個元素的記憶體;
tlist 中的 add 函式還同時觸動了乙個 notify 方法, 這應該是為它們的子類準備的(估計是用它來激發乙個事件的), 也不要了.
function tmylist.add(item: pointer): integer;再實現 tmylist.delete 過程.begin
if fcount = fcapacity then setcapacity(fcapacity + 4);
flist^[fcount] := item;
result := fcount;
inc(fcount);
end;
同前, 把錯誤處理也簡化成乙個異常; 也省略了對 notify 方法的觸動.
其中用到了 system.move, 可以參考:
這裡有乙個問題是需要高度注意的: tlist 在刪除乙個元素(它的元素就是指標)時, 並沒有釋放指標指向的物件, 只是從列表開除;
如果要同時 free 掉物件, 應該使用 contnrs 單元下的 tobjectlist 類.
procedure tmylist.delete(index: integer);還要實現 tmylist.setcount 方法.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;
之前我沒有想到 count 屬性還是可寫的; 這可夠狠的, 譬如已經有 100 個元素, 如果讓 count := 1; 這一下就要刪除後面 99 個元素!
還有不理解的是: 譬如已經有 100 個元素, 如果讓 count := 200; 那後面的 100 個元素即便是填充了空字元, 用指標讀過來也不是物件啊? 覺得不妥. 不過暫時也這樣了.
procedure tmylist.setcount(const value: integer);還有乙個 tmylist.clear 方法.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;
因為不用考慮列表中物件釋放的問題, 這個就簡單多了.
procedure tmylist.clear;至此, 已經宣告的方法都實現了, 這個 tmylist 類也該能湊合使用了.begin
setcount(0);
setcapacity(0);
end;
原始碼如下:
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就是通過建立並執行乙個匿名函式,在這個匿...