遲綁定早綁定

1、        概念
首先,什麼是綁定?( what`s the definition of binding? )

c++編程思想上有說到:
Connecting a function call to a function body is called binding.(將函數體和函數調用關聯起來,就叫綁定)
然後,那麼什麼是早綁定?(Early binding)
When binding is performed before the program is run (by the compiler and linker), it' s called early binding
在程序運行之前(也就是編譯和鏈接時),執行的綁定是早綁定。
然後,什麼是遲綁定?(late binding)
late binding, which means the binding occurs at runtime, based on the type of the object.
When a language implements late binding, there must be some mechanism to determine the

type of the object at runtime and call the appropriate member function

遲綁定發生在運行時,基於不同類型的對象。當一種語言實現遲綁定時,必須有某種機制確定對象的具體類型然後調用合適的成員函數。
2、         結論
2.1對於含有虛擬函數的類來說:
Ø        虛函數表是與類關聯的,也就是說,一個類只有一張虛函數表。(從這個方面上說,虛函數類似於類的靜態函數)(父類有一個Vtable,子類也有一個Vtable)
Ø        VTable中虛函數的位置是由基類決定的,所以,哪怕你在派生類中不是按基類的順序來重寫虛函數,派生類的VTable中虛函數的存放順序和基類的也是一樣的。
Ø        虛函數指針VPtr是與對象關聯的,每個對象都有一個虛函數指針,但是,同類的對象的虛函數指針的值是相同的。因爲都指向該類的虛函數表。
Ø        虛函數指針VPtr的值是在調用構造函數時進行初始化的(自動完成)。

2.2 C++遲綁定實現機理流程(編譯器都是類似於此種方式實現的):
(1)爲每個含有虛函數的類(基類以及派生類)都創建一張虛函數表(VTable,存儲於常量區),依次存放虛函數的地址。對於派生類來說,如果沒有重寫其基類的虛函數,那麼,將會在VTable中存放基類的虛函數地址。
(2)爲每個含有虛函數的類的對象,創建一個指針(VPtr),指向這個類的虛函數表(所以說,同類對象的VPtr的值是一樣的[*VPtr相同,但VPtr不同],也就是說,虛函數,在這一點上,類似於類的static函數,是所有對象共有的。)(此過程發生在運行期自動調用構造函數的過程中)
(3)通過強制轉換將派生類對象的地址/引用 賦給基類指針/變量(也就是向上類型轉換UpCasting)(此步決定了基類指針首先尋址的虛函數表,也就是現在派生類的虛函數表中尋址,如果在派生類的虛函數表中沒有找到此虛函數,則向上一級基類的虛函數表中尋找此虛函數,依次類推。由此可見,雖然代碼相同,卻實現了調用不同類函數的目的,也就是多態)
(4)然後,通過基類指針/引用對象 來調用虛函數(即:polymorphic call),就會通過此時基類對象的VPtr指針在所指向虛函數表中尋址(一般是從表頭地址開始,加上一定的偏移量)找到相應的函數地址,也就是之前派生類VPtr指針指向的虛函數表的函數地址。
 

2.3晚綁定原理
編譯器對每個包含虛函數的類創建一個表(稱爲V TA B L E)。在V TA B L E中,編譯器放置特定類的虛函數地址。在每個帶有虛函數的類中,編譯器祕密地置一指針,稱爲v p o i n t e r(縮寫爲V P T R),指向這個對象的V TA B L E。通過基類指針做虛函數調用時(也就是做多態調用時),編譯器靜態地插入取得這個V P T R,並在V TA B L E表中查找函數地址的代碼,這樣就能調用正確的函數使晚捆綁發生。爲每個類設置V TA B L E(編譯期)、初始化V P T R(運行期構造函數中)、爲虛函數調用插入代碼(運行期多態調用時),所有這些都是自動發生的,所以我們不必擔心這些。利用虛函數,這個對象的合適的函數就能被調用,哪怕在編譯器還不知道這個對象的特定類型的情況下。(《C++編程思想》)
2.4早綁定和晚綁定優缺點
早綁定,晚綁定,早晚都要綁定。綁定指在對象和其類型間建立關聯的過程。
早綁定指在對象申明的時候就和他的類型建立了關聯。
晚綁定是指我們的代碼在運行時再檢查對象是否提供了我們所需要的方法和屬性。
 很多人說C#和Java是早綁定的,javascript,python是遲綁定的,其實這個說法並不全對
一方面,C#和Java是強類型的,在變量聲明的時候就說明了類型,從這裏來講當然是早綁定的,於是我們才能在IDE中享受代碼提示帶來的方便,因爲ide通過你的申明就能知道你的對象是什麼類型,具有什麼方法和屬性,然後提示給你,同時編譯的時候也可以幫你檢查許多類型轉換的錯誤.

另一方面:無論C#和Java在實現他們很重要的一個功能:多態的時候,都是用晚綁定,比如你的父類中定義了virtual的方法,那麼這個方法可能會在你的子類中重載,具體你用什麼子類,是變量申明時所不知道的,在C++編譯器會在編譯的時候爲這些類加上一個指針,指針指向一個虛表,虛表中存在着真實的函數,這個是就是一個晚綁定了
早綁定的優點是:

Ø        編譯效率

Ø        代碼提示(代碼智能感知)

Ø        編譯時類型檢查

晚綁定的優點是:

Ø        不用申明類型

Ø        對象類型可以隨時更改

參考資料:
http://blog.csdn.net/faithmy509/archive/2009/05/21/4207625.aspx

http://www.cnblogs.com/yizhu2000/archive/2007/07/12/815628.html

http://blog.sina.com.cn/s/blog_63797eb20100gni8.html(C++ 多態遲綁定原理)

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/braveyly/archive/2010/05/03/5549978.aspx

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/braveyly/archive/2010/05/03/5549978.aspx

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/braveyly/archive/2010/05/03/5549978.aspx

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章