关于父类与子类的一点疑问、该如何处理
关于父类与子类的一点疑问、
(昨天自己去翻译一个C#的代码、那个泛型着实把我膈应了一把、好不容易改写完、也碰到一些小问题、我对于这些概念性的一直很模糊)
(昨天自己去翻译一个C#的代码、那个泛型着实把我膈应了一把、好不容易改写完、也碰到一些小问题、我对于这些概念性的一直很模糊)
- Delphi(Pascal) code
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type Aa = class(TObject) public constructor Create; destructor Destroy; function abc:Cardinal; //为了防止编译器优化掉循环 end; type Bb = class(Aa) public ss:TStringList;//用户占用内存方便观察 constructor Create; destructor Destroy; procedure Free; end; type TForm1 = class(TForm) btn1: TButton; btn2: TButton; btn3: TButton; btn4: TButton; btn5: TButton; btn6: TButton; btn7: TButton; btn8: TButton; procedure btn1Click(Sender: TObject); procedure btn2Click(Sender: TObject); procedure btn3Click(Sender: TObject); procedure btn4Click(Sender: TObject); procedure btn5Click(Sender: TObject); procedure btn6Click(Sender: TObject); procedure btn7Click(Sender: TObject); procedure btn8Click(Sender: TObject); procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} { Aa } function Aa.abc: Cardinal; begin Result:=Random(9999); end; constructor Aa.Create; begin inherited; end; destructor Aa.Destroy; begin inherited; end; { Bb } constructor Bb.Create; begin inherited; ss:=TStringList.Create; end; destructor Bb.Destroy; begin ss.Free; inherited; end; {如果自己写Free就需要这么写? procedure Bb.Free; begin if Self <> nil then Self.Destroy; Self:=nil; end; } procedure TForm1.btn1Click(Sender: TObject); //Create后不释放 var ii,rnd:Cardinal; k:Aa; begin for ii := 0 to 99999 do begin k:=Aa.Create; rnd:=k.abc; //防止编译器把循环给优化掉 end; ShowMessage(IntToStr(rnd) + #13 + '完成了'); //通过观察内存使用量、大概每次占用1.7M内存没有释放 end; procedure TForm1.btn2Click(Sender: TObject); var ii,rnd:Cardinal; k:Aa; begin for ii := 0 to 99999 do begin k:=Aa.Create; rnd:=k.abc; k.Destroy; end; ShowMessage(IntToStr(rnd) + #13 + '完成了'); //循环完毕、基本内存使用量无变化(几十K的变化、忽略) end; procedure TForm1.btn3Click(Sender: TObject); var ii,rnd:Cardinal; k:Aa; begin for ii := 0 to 99999 do begin k:=Aa.Create; rnd:=k.abc; k.Free; end; ShowMessage(IntToStr(rnd) + #13 + '完成了'); //循环完毕、基本内存使用量无变化(同调用Destroy方法) end; procedure TForm1.btn4Click(Sender: TObject); var ii,rnd:Cardinal; k:Aa; begin for ii := 0 to 99999 do begin k:=Aa.Create; rnd:=k.abc; FreeAndNil(k); end; ShowMessage(IntToStr(rnd) + #13 + '完成了'); //循环完毕、基本内存使用量无变化(同调用Destroy方法) end; //***********Bb类测试************************************ procedure TForm1.btn5Click(Sender: TObject); var ii,rnd:Cardinal; k:Bb; begin for ii := 0 to 99999 do begin k:=Bb.Create; rnd:=k.abc; //防止编译器把循环给优化掉 end; ShowMessage(IntToStr(rnd) + #13 + '完成了'); //通过观察内存使用量、大概每次占用9M内存没有释放 end; procedure TForm1.btn6Click(Sender: TObject); var ii,rnd:Cardinal; k:Bb; begin for ii := 0 to 99999 do begin k:=Bb.Create; rnd:=k.abc; //防止编译器把循环给优化掉 k.Destroy; end; ShowMessage(IntToStr(rnd) + #13 + '完成了'); //通过观察内存使用量、使用量基本无变化 end; procedure TForm1.btn7Click(Sender: TObject); var ii,rnd:Cardinal; k:Bb; begin for ii := 0 to 99999 do begin k:=Bb.Create; rnd:=k.abc; {防止编译器把循环给优化掉} k.Free; end; ShowMessage(IntToStr(rnd) + #13 + '完成了'); {通过观察内存使用量、每次有8M没有释放} end; procedure TForm1.btn8Click(Sender: TObject); var ii,rnd:Cardinal; k:Bb; begin for ii := 0 to 99999 do begin k:=Bb.Create; rnd:=k.abc; //防止编译器把循环给优化掉 FreeAndNil(k); end; ShowMessage(IntToStr(rnd) + #13 + '完成了'); //通过观察内存使用量、每次有8M没有释放 end; procedure TForm1.FormCreate(Sender: TObject); var k:Bb; begin k:=Bb.Create; ShowMessage(IntToStr(k.abc)); { //第一种方法 k.Free; //第二种方法 FreeAndNil(k); //第三种方法 k.Destroy; //第四种方法 //k.Destroy; k:=nil; } ShowMessage(IntToStr(k.abc)); //无论选择四种中的哪一种、依旧可以返回一个数值、这又是为什么呢? end; end.