請問一下物件的強制轉型compiler會在背後作出什麼事情呢?? |
尚未結案
|
chimera
初階會員 發表:62 回覆:78 積分:28 註冊:2003-03-22 發送簡訊給我 |
ex:
type TTest1 = class public x: integer; y: integer; end; TTest2 = class public z: integer; end; procedure TForm1.Button1Click(Sender: TObject); var test1: TTest1 ; test2: TTest2 ; begin test1:= test1.Create; test1.x := 1; test1.y := 2; test2:= ttest2(test1); //強制轉型 test2.z := 3; showmessage(inttostr(ttest1(test2).x)); //所得的x是3 showmessage(inttostr(ttest1(test2).y)); //所得的y是2那我很好奇的是在強制轉型時,compiler替我做了哪些事, 依照上面的實驗,DataField的部分,好像是會完整的複製資料流過去, 並且強制轉型還會替我們create一個新的實體, 而其他部分,我目前作出的實驗是VMT pointer, DMT pointer不改變, 因為是依照create出來的實體物件決定VMT pointer, DMT pointer 所以無論是向左或向右強制轉型,這兩個是都不會改變的 至於一般的method table pointer與property table pointer (姑且稱之,因為我不曉得除了VMT, DMT名稱之外的method table以及property table名稱)則會隨著所宣告的類別而改變, 也就是說當強制轉型時,就改變可用的一般method以及property(非 override的method), 例如: var test: TListBox; test2: tedit; begin test := TListBox.create(self); test2 := TEdit(test); //強制轉型 test2.Text := 'abc'; //可以使用edit的屬性及方法 showmessage(test2.Text); end;當然我知道上面的做法根本就是在玩火,但是我想知道compiler到底會做哪些事情,所以做了這種實驗 那我想知道我上面的結論是否是正確的,以及有哪些較完整的資料是屬於這方面相關的 發表人 - |
syntax
尊榮會員 發表:26 回覆:1139 積分:1258 註冊:2002-04-23 發送簡訊給我 |
你都不看書的嗎 ? 還是都只會看那種 "快快樂樂" 系列的書 ?
有很多有深度的書都有談到,也有很多英文的書說的更深,你可以找找,不難啊 同時你所提到的例子,在觀念上,你大部分都是錯誤的
1.DataField的部分,好像是會完整的複製資料流過去
沒有任何東西會被複製
2.強制轉型還會替我們create一個新的實體
沒有任何時體會被 create
3.根本沒有任何東西改變了 test1,test2 Hold 的內容只是一個指向該實體的物件指標
你只是將指標指向的位置重新導向
而在記憶體鋪陳架構上 x,y,z 都是 integer 而你的 class 有太簡單相近,所以在對應上 x 與 z 是安排在同一位置,也就是說 x , z 距離期物件實體開頭的位置相同,所以你可以使用該方式來改變其值,這根本就沒什麼 4.我想知道compiler到底會做哪些事情
那你就該去看 compiler 的書,而不是在這瞎猜吧 !
|
Jasonwong
版主 發表:49 回覆:931 積分:581 註冊:2006-10-27 發送簡訊給我 |
樓上的老兄...你的話是否也說的太重一點... 你會就很不了起嗎... 人家如果看的懂進階的書...還會跑來這裡問嗎...你忘了本站成立的宗旨嗎... 你知道就很不了起嗎... 請你下次回答時...口氣好一點...就算要罵人...也請不要帶髒字... --
聰明的人,喜歡猜心;雖然每次都猜對了,卻失去了自己的心
傻氣的人,喜歡給心;雖然每次都被笑了,卻得到了別人的心
------
聰明的人,喜歡猜心;雖然每次都猜對了,卻失去了自己的心 傻氣的人,喜歡給心;雖然每次都被笑了,卻得到了別人的心 |
chimera
初階會員 發表:62 回覆:78 積分:28 註冊:2003-03-22 發送簡訊給我 |
TTest1 = class public procedure hello; end; TTest2 = class public procedure hello; end; begin test1:= ttest1.Create; test2:= ttest2(test1); //強制轉型 test1.hello; test2.hello; end;抱歉把今天凌晨半睡半醒之間在很多段的例子中節錄下來的, 讓你覺得礙眼, 我會有前一個疑問是因為另外這個例子的緣故, 明明test2所參考到的實體是ttest1所建構出來的物件, 那變成在test2.hello這句裡, 所執行的是ttest2.hello的method, 所以我才誤認強制轉型會create一個新物件, 那經過強制轉型,在執行個別的method時, 會因為物件參考所被宣告的型別不同, 而改變他所會invoke的method 那這樣是在run time時改變同一個物件實體的程式進入點嗎?? |
chimera
初階會員 發表:62 回覆:78 積分:28 註冊:2003-03-22 發送簡訊給我 |
|
chimera
初階會員 發表:62 回覆:78 積分:28 註冊:2003-03-22 發送簡訊給我 |
TTest1 = class public procedure hello; end; TTest2 = class public procedure hello; end; procedure TTest1.hello; begin showmessage('hello in ttest1'); end; procedure TTest2.hello; begin showmessage('hello in ttest2'); end; procedure TForm1.Button1Click(Sender: TObject); var test1: ttest1; test2: ttest2; begin test1.hello; test2.hello; end;終於知道自己之前哪些觀念一直錯誤了, 原來我之前都一直以為method的程式進入點是跟著instance的, 也就是在物件的data field的資料裡面也包含program code進入點, 後來我做了上面的例子,就算完全不create物件, 也是可以直接執行,那就是說在編譯時期, compiler就已經幫我決定依照該object reference的type給予他program code的連結, 所以前面的例子無論我如何轉型,都是直接執行object reference所被宣告型別的method 可是這樣我又有另外一個問題了,那不create物件就可以直接invoke的話, 那這樣的靜態方法跟class method有什麼差別嗎??都可以不用create instance就直接invoke,差別就只有資格修飾子一個是class,一個是object,不是嗎?? 發表人 - chimera 於 2003/11/01 21:54:30 |
syntax
尊榮會員 發表:26 回覆:1139 積分:1258 註冊:2002-04-23 發送簡訊給我 |
引言: 樓上的老兄...你的話是否也說的太重一點... 你會就很不了起嗎... 人家如果看的懂進階的書...還會跑來這裡問嗎...你忘了本站成立的宗旨嗎... 你知道就很不了起嗎... 請你下次回答時...口氣好一點...就算要罵人...也請不要帶髒字... -- 聰明的人,喜歡猜心;雖然每次都猜對了,卻失去了自己的心 傻氣的人,喜歡給心;雖然每次都被笑了,卻得到了別人的心是啊! 你看到我罵人了 ? 還是你看到哪個髒字 ? 要他多去看書 , 錯了 ? --看不懂,可以針對不懂得部分發問, 只怕是好吃懶做, 連書都懶得看, 這樣的人才是汙辱本站宗旨的人, 在說這並不是什麼進階的問題, 這個觀念是很基本的物件導向程式設計時的觀念, 只是所謂 "快快樂樂" 系列的書, 都不會說"為什麼這樣做", 只會一昧的要你 Step by Step, never say why ! 很多有深度的書, 在最基礎的章節都會談到程式設計的概念, 有深度的書並不代表裡面的內容很困難, 很多有深度的書, 在章節鋪陳上也都是由簡單的到困難的內容, 有深度代表內容豐富有實質的內涵, 在去練練你的中文吧, 不要中文不好然後抓幾個字就發飆, 這樣才是有辱本站 要他別瞎猜, 瞎猜只是浪費時間 , 錯了 ? ---難道你是那種樂意看到別人永遠在瞎猜的人 ? 跟他解釋他在那, 就教罵人 ? ---你除了能批評以外, 還能做什麼, 長大一點, 用技術或觀念上的文字代替你無知的文字吧 ! Jasonwong 整篇,口氣不好的只有你 ps.念我的文章,請勿自己加入語氣變化,像念經一樣沒有語氣變化念出才對 發表人 - syntax 於 2003/11/02 21:49:50 |
syntax
尊榮會員 發表:26 回覆:1139 積分:1258 註冊:2002-04-23 發送簡訊給我 |
引言:1.method的程式進入點是跟著instance的 --這是對的,但是應該說是 method 的程式進入點是相對著 instance 的進入點 2.也就是在物件的data field的資料裡面也包含program code進入點, --不知你是怎麼想出這樣的結果,只是物件的data field的資料位置也只是相對著 instance 的進入點,含有物件本身的資料,而 Hold 進入點的,是存放創立時傳回值的那個變數 3.就算完全不create物件, 也是可以直接執行,那就是說在編譯時期,compiler就已經幫我決定依照該object reference的type給予他program code的連結 --是的,可以這樣做,但很不好,因為你用的是物件的本體宣告,因為物件的本體宣告也是一個完整的物件實體,而你 create 的,則是物件的一份 copy, 一旦本體有更動, copy 出來的也會有相同的更動, 這樣直接使用會在 OO 程式設計上產生無法預料的問題與難解的 Bug, 尤其在複雜的程式上 4.可是這樣我又有另外一個問題了,那不create物件就可以直接invoke的話, 那這樣的靜態方法跟class method有什麼差別嗎??都可以不用create instance就直接invoke,差別就只有資格修飾子一個是class,一個是object,不是嗎?? --這不是三言兩語就可以完全解釋的,不建立物件直接使用,是會出錯的,至於靜態的 procedure 跟 class procedure method 實作上的程式碼上其實是沒多大的不同,主要是物件的封裝理論,且靜態的只能有一份,clase method 可以有許多 instance,且可以使用 override overload ..等物件設計的能力,可以在有談到 functional programming 與 OO programming 之間的基本設計理念的文章中找到詳細的比較與解答TTest1 = class public procedure hello; end; TTest2 = class public procedure hello; end; procedure TTest1.hello; begin showmessage('hello in ttest1'); end; procedure TTest2.hello; begin showmessage('hello in ttest2'); end; procedure TForm1.Button1Click(Sender: TObject); var test1: ttest1; test2: ttest2; begin test1.hello; test2.hello; end;終於知道自己之前哪些觀念一直錯誤了, 原來我之前都一直以為method的程式進入點是跟著instance的, 也就是在物件的data field的資料裡面也包含program code進入點, 後來我做了上面的例子,就算完全不create物件, 也是可以直接執行,那就是說在編譯時期, compiler就已經幫我決定依照該object reference的type給予他program code的連結, 所以前面的例子無論我如何轉型,都是直接執行object reference所被宣告型別的method 可是這樣我又有另外一個問題了,那不create物件就可以直接invoke的話, 那這樣的靜態方法跟class method有什麼差別嗎??都可以不用create instance就直接invoke,差別就只有資格修飾子一個是class,一個是object,不是嗎?? 發表人 - chimera 於 2003/11/01 21:54:30 |
chimera
初階會員 發表:62 回覆:78 積分:28 註冊:2003-03-22 發送簡訊給我 |
引言: 1.method的程式進入點是跟著instance的 --這是對的,但是應該說是 method 的程式進入點是相對著 instance 的進入點這句看不太懂, 可能我所理解的"程式進入點"是錯的, 我想表達的"程式進入點"指的是在主程式中呼叫副程式時的那個進入點, 例如test.hello這句我原本錯誤的想法是:依址操作到test這個object instance後, 然後以為test這個object instance含有hello這個method實作。 而現在我所更正的想法是:test.hello這個函數會被compiler改成hello(@test) (這個轉換我是看C 完美經典這本書寫到的,我猜delphi應該也是依照同樣的手法吧), 取出test instance的位址傳進method中當作self這個隱藏參數的值, 此時compiler也會依照test的class,然後依照class的藍圖找到hello的program code實作區 引言: 2.也就是在物件的data field的資料裡面也包含program code進入點, --不知你是怎麼想出這樣的結果,只是物件的data field的資料位置也只是相對著 instance 的進入點,含有物件本身的資料,而 Hold 進入點的,是存放創立時傳回值的那個變數這也是我的誤解之一,因為我看錢達智的delphi學習筆記P.155頁時, 有一個VMT pointer講解是如何操作到virtual method, 可是整篇都沒講到instance method又是怎麼操作的, 所以我就以為instance method也跟VMT pointer一樣都是跟object instance一起create出來的 引言: 4.可是這樣我又有另外一個問題了,那不create物件就可以直接invoke的話, 那這樣的靜態方法跟class method有什麼差別嗎??都可以不用create instance就直接invoke,差別就只有資格修飾子一個是class,一個是object,不是嗎?? --這不是三言兩語就可以完全解釋的,不建立物件直接使用,是會出錯的,至於靜態的 procedure 跟 class procedure method 實作上的程式碼上其實是沒多大的不同,主要是物件的封裝理論,且靜態的只能有一份,clase method 可以有許多 instance,且可以使用 override overload ..等物件設計的能力,可以在有談到 functional programming 與 OO programming 之間的基本設計理念的文章中找到詳細的比較與解答受教了, 因為我看到講解像這類會牽扯到 程式語言對記憶體配置 的問題時, 都是講解一部分並非全貌,其他部分我就像瞎子摸象一般都要憑自己的猜測, 又會猜錯,所以才讓大家見笑了, 其實我發問時也知道object是一個reference, 但是因為誤解越來越大導致我誤以為cast時也會create object 像現在我對記憶體配置大概有 > 那能不能請 |
chimera
初階會員 發表:62 回覆:78 積分:28 註冊:2003-03-22 發送簡訊給我 |
引言: 是啊! 你看到我罵人了 ? 還是你看到哪個髒字 ? 要他多去看書 , 錯了 ? --看不懂,可以針對不懂得部分發問, 只怕是好吃懶做, 連書都懶得看, 這樣的人才是汙辱本站宗旨的人, 在說這並不是什麼進階的問題, 這個觀念是很基本的物件導向程式設計時的觀念, 只是所謂 "快快樂樂" 系列的書, 都不會說"為什麼這樣做", 只會一昧的要你 Step by Step, never say why ! 很多有深度的書, 在最基礎的章節都會談到程式設計的概念, 有深度的書並不代表裡面的內容很困難, 很多有深度的書, 在章節鋪陳上也都是由簡單的到困難的內容, 有深度代表內容豐富有實質的內涵, 在去練練你的中文吧, 不要中文不好然後抓幾個字就發飆, 這樣才是有辱本站 要他別瞎猜, 瞎猜只是浪費時間 , 錯了 ? ---難道你是那種樂意看到別人永遠在瞎猜的人 ? 跟他解釋他在那, 就教罵人 ? ---你除了能批評以外, 還能做什麼, 長大一點, 用技術或觀念上的文字代替你無知的文字吧 ! Jasonwong 整篇,口氣不好的只有你 ps.念我的文章,請勿自己加入語氣變化,像念經一樣沒有語氣變化念出才對syntax的那篇文章語氣在一般人唸起來想要沒變化真的是漫困難的, 基本上字詞本身就會代表作者本身的語氣, 我自己念起來也覺得我好像在討罵 不過人的爭執就都起於誤解,好了, 別為了我那一開始誤入歧途的想法在吵, 兩位都是高手沒必要在這種地方上爭執 發表人 - |
code6421
版主 發表:43 回覆:223 積分:208 註冊:2002-08-16 發送簡訊給我 |
引言: ------------------- 1.method的程式進入點是跟著instance的 --這是對的,但是應該說是 method 的程式進入點是相對著 instance 的進入點 ------------- 這句看不太懂, 可能我所理解的"程式進入點"是錯的, 我想表達的"程式進入點"指的是在主程式中呼叫副程式時的那個進入點, 例如test.hello這句我原本錯誤的想法是:依址操作到test這個object instance後, 然後以為test這個object instance含有hello這個method實作。 而現在我所更正的想法是:test.hello這個函數會被compiler改成hello(@test) (這個轉換我是看C 完美經典這本書寫到的,我猜delphi應該也是依照同樣的手法吧), 取出test instance的位址傳進method中當作self這個隱藏參數的值, 此時compiler也會依照test的class,然後依照class的藍圖找到hello的program code實作區語意學上,Instance與Method是一體的,但在Compiler學上看來就不應該如此, 所有位於Class內的Member Function(non-virtual)與Instance是無關的,當使用 a.a()時,實際的呼叫是a.(a),Object Reference會被傳入,這也是Self/this 能運作的原因,這樣做的好處是減少Object佔用記憶體的大小與執行效率,缺點 就是違反語意學,當Member Function屬於virtual時,Instance與Method是 一體的,這是因為需要經由VMT來處理覆載課題的緣故. C /Pascal都採用此種方式.Java/C#等解譯性語言就不是這麼做,而是採 用Dynamic Resolve方式,這也代表著你無法使用一個不正確的 Object Reference來呼叫Member function.這個問題背後所隱含的技術相當 廣,看看Compiler的書籍再看看DELPHI所編譯出來的程式碼,你會發現進入的是 另一個世界. 另外,此行為屬於Compiler議決,因此沒有任何官方認可,出現不一樣的行為也 非 Compiler之錯. Just coding... Taiwan:http://code6421.ktop.com.tw China:http://home.hoolee.com/~code6421 發表人 - code6421 於 2003/11/03 19:20:40 發表人 - code6421 於 2003/11/03 19:21:59 發表人 - code6421 於 2003/11/03 19:22:35
------
Just codeing... |
chimera
初階會員 發表:62 回覆:78 積分:28 註冊:2003-03-22 發送簡訊給我 |
引言: 看看Compiler的書籍再看看DELPHI所編譯出來的程式碼,你會發現進入的是 另一個世界.請問一下這兩本compiler的書對於基本以及OO方面寫的好不好呢?? 書名: Modern Compiler Design 作者: Dick Grune, Henri E. Bal, Ceriel J.H. Jacobs, Koen G. Langendoenm 出版社: WILEY 書名: Crafting a Compiler with C 作者 Charles N. Fischer, Richard J. Jr. Leblanc 出版社 Addison Wesley. |
code6421
版主 發表:43 回覆:223 積分:208 註冊:2002-08-16 發送簡訊給我 |
引言: 請問一下這兩本compiler的書對於基本以及OO方面寫的好不好呢?? 書名: Modern Compiler Design 作者: Dick Grune, Henri E. Bal, Ceriel J.H. Jacobs, Koen G. Langendoenm 出版社: WILEY 書名: Crafting a Compiler with C 作者 Charles N. Fischer, Richard J. Jr. Leblanc 出版社 Addison Wesley.第一本曾出現在我的書單上,第二本沒聽過... Amazon上的評價可以去看看. Just coding... Taiwan:http://code6421.ktop.com.tw China:http://home.hoolee.com/~code6421
------
Just codeing... |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |