苛评VCL: 接口与TObject
在李維的《inside VCL》中詳細(xì)描述了VCL中TObject的地位。是的Borland的工程師們有心將Delphi語言做成pure language。所以你幾乎可以看到TObject的所有pure pascal的實(shí)現(xiàn)。
更重要的,你應(yīng)該會發(fā)現(xiàn)。Delphi將代碼的所有運(yùn)行機(jī)制都暴露在我們面前。這也就是Delphi的TObject和C++中的Object以及C#的Object有很大不同的地方。
Delphi將整個語言的機(jī)制都在TObject上實(shí)現(xiàn)了。消息機(jī)制、接口機(jī)制、面向?qū)ο髾C(jī)制(多態(tài))等等你都可以從TObject的實(shí)現(xiàn)代碼中看到運(yùn)行的全部流程。
不管TObject如何優(yōu)秀,可是TObject正如Borland一樣,在它身上總是看到受制于MS的影子。特別是接口機(jī)制。我有兩點(diǎn)認(rèn)為TObject的設(shè)計(jì)不好。
先說說我第一個不滿意的地方。說是第一,并不表示是“最”的意思。只是代表“最先”的意思。
在Delphi的TObject中,類在實(shí)現(xiàn)了接口之后,其創(chuàng)建的實(shí)例中,對象指針和接口指針并不是同一個地址。這個可能大家沒有注意到,但是主要通過簡單的例子(取兩個指針的地址)就可以發(fā)現(xiàn)這個現(xiàn)象。
你可能不會在意這個差異。是的,其實(shí)也沒什么,不是同一個地址,代碼照樣可以工作。在對象的內(nèi)存實(shí)例模型中,接口的指針直接存儲在屬性后面(如果存在繼承,可能會出現(xiàn)交錯的)。因?yàn)門Object設(shè)計(jì)的時候,兩個地址不在一起,那么就存在兩個問題:
- 如果從對象轉(zhuǎn)換到接口
- 如何從接口轉(zhuǎn)換到對象
稍微知道對象模型的人,就應(yīng)該知道對象調(diào)用虛擬方法表的過程。只有對象指針可以指向VMT。另外,在接口訪問方法的實(shí)現(xiàn)代碼的時候,也需要傳入對象指針。這是為什么?我們知道,一個對象的方法中,有一個隱含的指針,我們一般稱它為Self指針。只要不是class function,那么這個Self指針就是指向?qū)ο髮?shí)例的指針。所以在代碼的調(diào)用過程中,必然有這個轉(zhuǎn)換。
TObject提供的AS操作,可以完成第1個轉(zhuǎn)換,但是可惜的是,TObject并沒有提供一個公開的方法來負(fù)責(zé)第2個轉(zhuǎn)換。這是我認(rèn)為TObject在這方面設(shè)計(jì)不好的原因。(JCL代碼庫中有第2個轉(zhuǎn)換的代碼)
第二個我不滿意的地方就是TObject在生存期管理上,沒有做到和接口一致。我相信這也是許多使用Delphi接口的同志們一致的想法。雖然我們現(xiàn)在看到Java和C#都已經(jīng)做到這點(diǎn),可不能不指出的是,在Delphi中,對象和接口不可以混用!
我并不是奢求TObject的生存期可以自管理。畢竟,我還是習(xí)慣了“誰創(chuàng)建誰釋放”的規(guī)則。可是一旦到了接口和對象混合使用的時候,就發(fā)生了問題。
這雖然可以解釋為接口是Delphi為了迎合COM而后加上的。我們今天卻應(yīng)該來設(shè)計(jì)一下一種規(guī)則,來解決接口混用的問題。我認(rèn)為可以有一種簡單的方式:TObject在Free的時候,發(fā)現(xiàn)其接口引用計(jì)數(shù)不為0的時候,不會Destroy。
目前我們無法做到這點(diǎn),這是因?yàn)镈estroy是Delphi默認(rèn)做的,也就是說,只要調(diào)用了Free方法,Destroy必然發(fā)生。我們無法完美地改變這個現(xiàn)實(shí)。也正因?yàn)榇?#xff0c;我才認(rèn)為必須在設(shè)計(jì)TObject的時候,將這個考慮進(jìn)去!
OK。嘗試重新審視VCL中的各個基礎(chǔ)類,其實(shí)有點(diǎn)大膽。所以用“苛評”這個詞來做標(biāo)題,表明這完全是我的苛刻,VCL的設(shè)計(jì)是非常棒的。不過也算是我使用6年Delphi的一點(diǎn)回報(bào)吧。以后還會繼續(xù)苛評其他類。希望大家繼續(xù)關(guān)注。
轉(zhuǎn)載于:https://www.cnblogs.com/ohmyjava/archive/2007/02/02/2141942.html
總結(jié)
以上是生活随笔為你收集整理的苛评VCL: 接口与TObject的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Web.config详解
- 下一篇: 关于vc中Warning: skippi