轉載:http://www.yesky.com/23/1621023.shtml
聯編是指一個電腦程式自身彼此關聯的過程。按照聯編所進行的階段不同,可分為兩種不同的聯編方法:靜態聯編和動態聯編。
靜態聯編
靜態聯編是指聯編工作出現在編譯串連階段,這種聯編又稱早期聯編,因為這種聯編過程是在程式開始運行之前完成的。
在編譯時間所進行的這種聯編又稱靜態束定。在編譯時間就解決了程式中的操作調用與執行該作業碼間的關係,確定這種關係又稱為束定,在編譯時間束定又稱靜態束定。下面舉一個靜態聯編的例子。
#include class Point { public: Point(double i, double j) { x=i; y=j; } double Area() const { return 0.0; } private: double x, y; }; class Rectangle:public Point { public: Rectangle(double i, double j, double k, double l); double Area() const { return w*h; } private: double w, h; }; Rectangle::Rectangle(double i, double j, double k, double l):Point(i, j) { w=k; h=l; } void fun(Point &s) { cout<<s.area()<<endl; } void main() { Rectangle rec(3.0, 5.2, 15.0, 25.0); fun(rec); } 該程式的運行結果為: 0 |
輸出結果表明在fun()函數中,s所引用的對象執行的Area()操作被關聯到Point::Area()的實現代碼上。這是因為靜態聯編的結果。在程式編譯階段,對s所引用的對象所執行的Area()操作只能束定到Point類的函數上。因此,導致程式輸出了所不期望的結果。因為我們期望的是s引用的對象所執行的Area()操作應該束定到Rectangl類的Area()函數上。這是靜態聯編所達不到的。
動態聯編
從對靜態聯編的上述分析中可以知道,編譯器在編譯階段並不能確切知道將要調用的函數,只有在程式執行時才能確定將要調用的函數,為此要確切知道該調用的函數,要求聯編工作要在程式運行時進行,這種在程式運行時進行聯編工作被稱為動態聯編,或稱動態束定,又叫晚期聯編。
動態聯編實際上是進行動態識別。在上例中,前面分析過了靜態聯編時,fun()函數中s所引用的對象被束定到Point類上。而在運行時進行動態聯編將把s的對象引用束定到Rectangle類上。可見,同一個對象引用s,在不同階段被束定的類對象將是不同的。那麼如何來確定是靜態聯編還是動態聯編呢?C++規定動態聯編是在虛函數的支援下實現的。
從上述分析可以看出靜態聯編和動態聯編也都是屬於多態性的,它們是不同階段對不同實現進行不同的選擇。上例中,實現上是對fun()函數參數的多態性的選擇。該函數的參數是一個類的對象引用,靜態聯編和動態聯編和動態聯編實際上是在選擇它的靜態類型和動態類型。聯編是對這個引用的多態性的選擇。
這個是從另一篇中找到的可能更加容易理解:
聯編就是將模組或者函數合并在一起產生可執行代碼的處理過程,同時對每個模組或者函數調用分配記憶體位址,並且對外部存取也分配正確的記憶體位址,它是電腦程式彼此關聯的過程。按照聯編所進行的階段不同,可分為兩種不同的聯編方法:靜態聯編和動態聯編。
靜態聯編是指在編譯階段就將函數實現和函數調用關聯起來,因此靜態聯編也叫早綁定,在編譯階段就必須瞭解所有的函數或模組執行所需要檢測的資訊,它對函數的選擇是基於指向對象的指標(或者引用)的類型,C語言中,所有的聯編都是靜態聯編,據我所知道的,任何一種編譯器都支援靜態聯編(廢話)。
動態聯編是指在程式執行的時候才將函數實現和函數調用關聯,因此也叫運行時綁定或者晚綁定,動態聯編對函數的選擇不是基於指標或者引用,而是基於物件類型,不同的物件類型將做出不同的編譯結果。C++中一般情況下聯編也是靜態聯編,但是一旦涉及到多態和虛擬函數就必須要使用動態聯編了。下面將介紹一下多態。
多態:字面的含義是具有多種形式或形態。C++多態有兩種形式,動態多態和靜態多態;動態多態是指一般的多態,是通過類繼承和虛函數機制實現的多態;靜態多態是通過模板來實現,因為這種多態實在編譯時間而非運行時,所以稱為靜態多態。