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