為何使用Interface會出現Access violation? |
|
pedro
尊榮會員 發表:152 回覆:1187 積分:892 註冊:2002-06-12 發送簡訊給我 |
請問我使用下面的程式碼,為何出現記憶體錯誤,是我那邊觀念不對麼? 請大大們指教,謝謝 type
function TBird.Jump: string; procedure TForm5.Button1Click(Sender: TObject);
|
aftcast
站務副站長 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
post半天沒人回,我就閒閒插花一下好了。 ===================引 用 文 章=================== 請問我使用下面的程式碼,為何出現記憶體錯誤,是我那邊觀念不對麼? 請大大們指教,謝謝
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan |
pcplayer99
尊榮會員 發表:146 回覆:790 積分:632 註冊:2003-01-21 發送簡訊給我 |
===================引 用 文 章=================== 請問我使用下面的程式碼,為何出現記憶體錯誤,是我那邊觀念不對麼? 請大大們指教,謝謝 type
function TBird.Jump: string; procedure TForm5.Button1Click(Sender: TObject);
=======================================
你好。把你的城市改一下就没问题了: procedure TForm1.Button1Click(Sender: TObject); 你的程序和我的可以正常执行的程序的区别是: 1. 我的: if supports(source,ICanJump,CanJump) then 2. 你的: if supports(source,ICanJump) then 你可以看看 Delphi 的 Help 关于 supports: function Supports(const Instance: IInterface ; const IID: TGUID; out Intf): Boolean; overload; function Supports(const Instance: TObject; const IID: TGUID; out Intf): Boolean; overload; function Supports(const AClass: TClass; const IID: TGUID): Boolean; overload; 注意 help 里的这一句: If Instance supports the interface, Supports returns the interface as the Intf parameter and returns true. If AClass supports the interface, Supports does not return an interface, but still returns true. 你的程序实际上是采用了:function Supports(const AClass: TClass; const IID: TGUID): Boolean; overload; 而这个是检查一个 Class 是否支持某个 Interface,并不会返回一个 Interface 的实例,亦即其实例是 nil,调用它,当然 AV。 我使用了 function Supports(const Instance: TObject; const IID: TGUID; out Intf): Boolean; overload; 这一句,是检查某个对象(也就是某个类的实例)是否支持某个 Interface,如果支持,返回的第三个参数就是它实现的 Interface 的实例。因此可以正确调用那个 Interface。 其实,很多时候,只需要去看看 Help 就很清楚了。 |
aftcast
站務副站長 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
原來delphi中使用interface的方法和c 有一樣,也有不一樣。 一樣的地方是無法直接把instance直接upcast(向上轉型)就可以使用interface。因此原出題人使用source as ICanJump;這句話會失效! 學習了!
source:=TBird.Create;
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan |
pedro
尊榮會員 發表:152 回覆:1187 積分:892 註冊:2002-06-12 發送簡訊給我 |
謝謝aftcast及pcplayer99大大的回應 特別是pcplayer99告知小弟supports還有另一個重載式可供取得interface, 經修改後如下,可以執行無誤了,謝謝您們 type TBird=class(TInterfacedObject,ICanJump) TBird1=class(TBird) TBird2=class(TBird) function TBird1.Jump: string; function TBird2.Jump: string; procedure TForm3.Button1Click(Sender: TObject); |
pedro
尊榮會員 發表:152 回覆:1187 積分:892 註冊:2002-06-12 發送簡訊給我 |
延續這個問題,再做變化,請教兩位大大, 下面的程式碼為何DoIt2有時會執行到有時不會,執行到還會AV錯誤? 依小弟的見解,IOne(Intf).DoIt執行完畢時,介面Intf會被釋放,而物件person並末釋放,我再次去取得ITwo介面,理應可取得及完整執行才對,這邊實在不解? type ITwo=Interface TPerson=class(TInterfacedObject,IOne,ITwo) procedure TPerson.DoIt1; procedure TPerson.DoIt2; procedure TPerson.DoNomal; procedure TForm1.Button1Click(Sender: TObject);
|
pcplayer99
尊榮會員 發表:146 回覆:790 積分:632 註冊:2003-01-21 發送簡訊給我 |
procedure TForm1.Button1Click(Sender: TObject);
var person:TPerson; Intf:IInterface; begin person:=TPerson.Create; if supports(person,IOne,intf) then IOne(Intf).DoIt; 《--- 执行到这里, Intf 还在。如果这时候,这个方法结束,比如: end; <--- 方法立即结束。因为离开了这个方法,这个方法的局部的变数 intf 自动被清除,就会导致 Person 的 interface 的引用计数为 0 而导致 Person 被释放。 但你的程式并没有立即结束。这时候,如果写成: procedure TForm1.Button1Click(Sender: TObject); var person:TPerson; Intf:IInterface; begin person:=TPerson.Create; if supports(person,IOne,intf) then IOne(Intf).DoIt; Intf := nil; Person.DoSometing.....; <--- 因为前面释放了它的 interface ,会导致 Person 被自动 Free,结果,这句肯定会出 AV 错误。 end; 所以,你的程式: procedure TForm1.Button1Click(Sender: TObject); 对于上述代码,实际写程式的时候,千万别这样写。因为这样很不确定。 ===================引 用 文 章=================== 延續這個問題,再做變化,請教兩位大大, 下面的程式碼為何DoIt2有時會執行到有時不會,執行到還會AV錯誤? 依小弟的見解,IOne(Intf).DoIt執行完畢時,介面Intf會被釋放,而物件person並末釋放,我再次去取得ITwo介面,理應可取得及完整執行才對,這邊實在不解? type ITwo=Interface TPerson=class(TInterfacedObject,IOne,ITwo) procedure TPerson.DoIt1; procedure TPerson.DoIt2; procedure TPerson.DoNomal; procedure TForm1.Button1Click(Sender: TObject);
|
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |