诚心求教对象引用与克隆问题
我正在看刘艺写的《Delphi面向对象编程思想》。看到此处有个不明白的地方。
3.1.5 对象的克隆:
书中举了个例子
(问题点1)
var a,b:TMyObject;
begin
a:=TMyObject.create;
b:=TMyObject.create;
b:=a;//错误,对象b丢失导致内存泄露。
end;
然后说明不应用b:=a;的形式,应写成b.assign(a);
以上说的我明白,即a和b各引用了不同的空间,而b:=a;这样的话b的那块空间就泄露了。所以用b.assign(a);这种是把值赋过来,而a和b还是有各自的空间。然后请往下看:
书中举了个例子,恢复字体的,是错误的方法
这个例子的想法是:初始memo中的字体是黑色的,然后点设置按钮设置后(比如设置成了红色),memo字体变为红色。再点恢复按钮后memo字体又变成了黑色。
但是问题点2是错误的,点恢复后恢复不成。
(问题点2)
FOriginalFont:TFont;
procedure TForm1.btnSetClick(Sender:TObject);//设置按钮
begin
if fontdialog1.Execute then
Memo1.Font:=FontDialog1.Font;
end;
procedure TForm1.FormCreate(Sender:TObject);
begin
Memo1.Lines.Add('某某某');
FOriginalFont:=Memo1.Font;
end;
procedure TForm1.btnundoClick(Sender:TObject);//恢复按钮
begin
Memo1.Font:=FOriginalFont;//Memo1.Font和FOriginalFont实际上引用的是同一个对象
end;
end.
然后举了个例子,是正确的方法
(问题点3)
FOriginalFont:TFont;
procedure TForm1.btnSetClick(Sender:TObject);
begin
if fontdialog1.Execute then
Memo1.Font:=FontDialog1.Font;
end;
procedure TForm1.FormCreate(Sender:TObject);
begin
Memo1.Lines.Add('某某某');
FOriginalFont:=TFont.create;
FOriginalFont.assign(Memo1.Font);
end;
procedure TForm1.btnundoClick(Sender:TObject);
begin
Memo1.Font.Assign(FOriginalFont);
end;
end.
问题点2和问题点3我也明白为什么对和错。2和3的区别主要是create事件中FOriginalFont的处理方法。然后我进行了机上实验,把问题点3改了一下:
(问题点4)
FOriginalFont:TFont;
procedure TForm1.btnSetClick(Sender:TObject);
begin
if fontdialog1.Execute then
Memo1.Font:=FontDialog1.Font;
end;
procedure TForm1.FormCreate(Sender:TObject);
begin
Memo1.Lines.Add('某某某');
FOriginalFont:=TFont.create;
FOriginalFont.assign(Memo1.Font);
end;
procedure TForm1.btnundoClick(Sender:TObject);
begin
Memo1.Font:=FOriginalFont;
end;
end.
问题点3和4的区别就最后1句话,一种是用assign(),一种是用:=。而问题点4的写法也能得到正确的结果,即可以恢复字体。
根据以上的例子,我得出结论并有问题。请帮我看下我的结论对不对,如果不对,请帮我更正我的看法。并帮我解答我的问题,谢谢!
结论:
因为问题点4可以得到正确的结果,所以b:=a;只看这个语句,这种写法,是b引用a的空间。a的空间变了,b才变。而之后无论b的空间变与不变,不影响a.(如问题点2.上来就FOriginalFont:=Memo1.Font;而之后Memo1.Font变了,所以FOriginalFont也变了。所以最后结果不正确。而如问题点4.最后写成Memo1.Font:=FOriginalFont的形式,如果设置并恢复很多次memo1,FOriginalFont也不会变,还是初始的黑色字体,所以问题点4能正确运行)
问题:
关于问题点1的内存泄露问题。问题点2,3,4不存在这种问题么?问题点3是书中完全正确的例子,就拿问题点3来说。memo1.font有一块空间。而Memo1.Font:=FontDialog1.Font;这句,Memo1.Font的空间不就指成了FontDialog1.Font的空间了么,Memo1.Font的空间不也泄露了么。要我说就换成Memo1.Font.assign(FontDialog1.Font);所以我觉得问题点2,3,4中font部分只要用了:=符号,都有这个问题.(因为FOriginalFont,Memo1.Font,fontdialog1这3个应该是都有各自的空间的,只要用了:=,就应该出问题点1的内存泄露问题)。而2,3,4为什么没有出1中的内存泄露问题呢?
我是新手,对引用与克隆这块不是很明白,有可能我的结论和问题中的话本身就有概念问题,请帮忙更正过来。请帮我解释下我的问题,如果我有概念性错误,也请帮我解答。我主要是想把这块搞明白,谢谢!