全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1631
推到 Plurk!
推到 Facebook!

請問一下物件的強制轉型compiler會在背後作出什麼事情呢??

尚未結案
chimera
初階會員


發表:62
回覆:78
積分:28
註冊:2003-03-22

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-11-01 01:52:28 IP:211.76.xxx.xxx 未訂閱
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

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-11-01 11:26:55 IP:203.203.xxx.xxx 未訂閱
你都不看書的嗎 ? 還是都只會看那種 "快快樂樂" 系列的書 ? 有很多有深度的書都有談到,也有很多英文的書說的更深,你可以找找,不難啊 同時你所提到的例子,在觀念上,你大部分都是錯誤的 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

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-11-01 12:34:33 IP:203.204.xxx.xxx 未訂閱
樓上的老兄...你的話是否也說的太重一點... 你會就很不了起嗎... 人家如果看的懂進階的書...還會跑來這裡問嗎...你忘了本站成立的宗旨嗎... 你知道就很不了起嗎... 請你下次回答時...口氣好一點...就算要罵人...也請不要帶髒字... -- 聰明的人,喜歡猜心;雖然每次都猜對了,卻失去了自己的心 傻氣的人,喜歡給心;雖然每次都被笑了,卻得到了別人的心
------
聰明的人,喜歡猜心;雖然每次都猜對了,卻失去了自己的心
傻氣的人,喜歡給心;雖然每次都被笑了,卻得到了別人的心
chimera
初階會員


發表:62
回覆:78
積分:28
註冊:2003-03-22

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-11-01 12:59:35 IP:211.76.xxx.xxx 未訂閱
  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

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-11-01 13:03:37 IP:211.76.xxx.xxx 未訂閱
引言: 樓上的老兄...你的話是否也說的太重一點... 你會就很不了起嗎... 人家如果看的懂進階的書...還會跑來這裡問嗎...你忘了本站成立的宗旨嗎... 你知道就很不了起嗎... 請你下次回答時...口氣好一點...就算要罵人...也請不要帶髒字...
沒關係啦,我自覺得我的問題問的也不是很好, 因為例子沒有帶齊,所以導致他人的誤會, 只要能夠讓我的邏輯更正確,我都虛心接受
chimera
初階會員


發表:62
回覆:78
積分:28
註冊:2003-03-22

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-11-01 18:46:58 IP:211.76.xxx.xxx 未訂閱
  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

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-11-02 21:47:14 IP:203.203.xxx.xxx 未訂閱
引言: 樓上的老兄...你的話是否也說的太重一點... 你會就很不了起嗎... 人家如果看的懂進階的書...還會跑來這裡問嗎...你忘了本站成立的宗旨嗎... 你知道就很不了起嗎... 請你下次回答時...口氣好一點...就算要罵人...也請不要帶髒字... -- 聰明的人,喜歡猜心;雖然每次都猜對了,卻失去了自己的心 傻氣的人,喜歡給心;雖然每次都被笑了,卻得到了別人的心
是啊! 你看到我罵人了 ? 還是你看到哪個髒字 ? 要他多去看書 , 錯了 ? --看不懂,可以針對不懂得部分發問, 只怕是好吃懶做, 連書都懶得看, 這樣的人才是汙辱本站宗旨的人, 在說這並不是什麼進階的問題, 這個觀念是很基本的物件導向程式設計時的觀念, 只是所謂 "快快樂樂" 系列的書, 都不會說"為什麼這樣做", 只會一昧的要你 Step by Step, never say why ! 很多有深度的書, 在最基礎的章節都會談到程式設計的概念, 有深度的書並不代表裡面的內容很困難, 很多有深度的書, 在章節鋪陳上也都是由簡單的到困難的內容, 有深度代表內容豐富有實質的內涵, 在去練練你的中文吧, 不要中文不好然後抓幾個字就發飆, 這樣才是有辱本站 要他別瞎猜, 瞎猜只是浪費時間 , 錯了 ? ---難道你是那種樂意看到別人永遠在瞎猜的人 ? 跟他解釋他在那, 就教罵人 ? ---你除了能批評以外, 還能做什麼, 長大一點, 用技術或觀念上的文字代替你無知的文字吧 ! Jasonwong 整篇,口氣不好的只有你 ps.念我的文章,請勿自己加入語氣變化,像念經一樣沒有語氣變化念出才對 發表人 - syntax 於 2003/11/02 21:49:50
syntax
尊榮會員


發表:26
回覆:1139
積分:1258
註冊:2002-04-23

發送簡訊給我
#8 引用回覆 回覆 發表時間:2003-11-02 22:15:54 IP:203.203.xxx.xxx 未訂閱
引言:
  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
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 之間的基本設計理念的文章中找到詳細的比較與解答
chimera
初階會員


發表:62
回覆:78
積分:28
註冊:2003-03-22

發送簡訊給我
#9 引用回覆 回覆 發表時間:2003-11-02 23:03:45 IP:211.76.xxx.xxx 未訂閱
引言: 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

發送簡訊給我
#10 引用回覆 回覆 發表時間:2003-11-02 23:18:36 IP:211.76.xxx.xxx 未訂閱
引言: 是啊! 你看到我罵人了 ? 還是你看到哪個髒字 ? 要他多去看書 , 錯了 ? --看不懂,可以針對不懂得部分發問, 只怕是好吃懶做, 連書都懶得看, 這樣的人才是汙辱本站宗旨的人, 在說這並不是什麼進階的問題, 這個觀念是很基本的物件導向程式設計時的觀念, 只是所謂 "快快樂樂" 系列的書, 都不會說"為什麼這樣做", 只會一昧的要你 Step by Step, never say why ! 很多有深度的書, 在最基礎的章節都會談到程式設計的概念, 有深度的書並不代表裡面的內容很困難, 很多有深度的書, 在章節鋪陳上也都是由簡單的到困難的內容, 有深度代表內容豐富有實質的內涵, 在去練練你的中文吧, 不要中文不好然後抓幾個字就發飆, 這樣才是有辱本站 要他別瞎猜, 瞎猜只是浪費時間 , 錯了 ? ---難道你是那種樂意看到別人永遠在瞎猜的人 ? 跟他解釋他在那, 就教罵人 ? ---你除了能批評以外, 還能做什麼, 長大一點, 用技術或觀念上的文字代替你無知的文字吧 ! Jasonwong 整篇,口氣不好的只有你 ps.念我的文章,請勿自己加入語氣變化,像念經一樣沒有語氣變化念出才對
syntax的那篇文章語氣在一般人唸起來想要沒變化真的是漫困難的, 基本上字詞本身就會代表作者本身的語氣, 我自己念起來也覺得我好像在討罵 不過人的爭執就都起於誤解,好了, 別為了我那一開始誤入歧途的想法在吵, 兩位都是高手沒必要在這種地方上爭執 發表人 -
code6421
版主


發表:43
回覆:223
積分:208
註冊:2002-08-16

發送簡訊給我
#11 引用回覆 回覆 發表時間:2003-11-03 19:19:27 IP:61.216.xxx.xxx 未訂閱
引言: ------------------- 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

發送簡訊給我
#12 引用回覆 回覆 發表時間:2003-11-03 20:03:57 IP:211.76.xxx.xxx 未訂閱
引言: 看看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

發送簡訊給我
#13 引用回覆 回覆 發表時間:2003-11-03 21:50:16 IP:61.216.xxx.xxx 未訂閱
引言: 請問一下這兩本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...
系統時間:2024-05-04 23:33:28
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!