1. 程式人生 > >C++的靜態聯編和動態聯編技術

C++的靜態聯編和動態聯編技術

聯編是指一個計算機程式自身彼此關聯的過程。按照聯編所進行的階段不同,可分為兩種不同的聯編方法:靜態聯編和動態聯編。 

靜態聯編 

靜態聯編是指聯編工作出現在編譯連線階段,這種聯編又稱早期聯編,因為這種聯編過程是在程式開始執行之前完成的。 

在編譯時所進行的這種聯編又稱靜態束定。在編譯時就解決了程式中的操作呼叫與執行該操作程式碼間的關係,確定這種關係又稱為束定,在編譯時束定又稱靜態束定。下面舉一個靜態聯編的例子。 

#include <iostream> 
using namespace std; 

class Point 

public: 
Point(double i, double j) { x=i; y=j; } 
virtual double Area() const { return 0.0; } 
//virtual 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, 10.0, 10.0); 
fun(rec); 

該程式的執行結果為: 




輸出結果表明在fun()函式中,s所引用的物件執行的Area()操作被關聯到Point::Area()的實現程式碼上。這是因為靜態聯編的結果。在程式編譯階段,對s所引用的物件所執行的Area()操作只能束定到Point類的函式上。因此,導致程式輸出了所不期望的結果。因為我們期望的是s引用的物件所執行的Area()操作應該束定到Rectangl類的Area()函式上。這是靜態聯編所達不到的。 

動態聯編 

從對靜態聯編的上述分析中可以知道,編譯程式在編譯階段並不能確切知道將要呼叫的函式,只有在程式執行時才能確定將要呼叫的函式,為此要確切知道該呼叫的函式,要求聯編工作要在程式執行時進行,這種在程式執行時進行聯編工作被稱為動態聯編,或稱動態束定,又叫晚期聯編。 

動態聯編實際上是進行動態識別。在上例中,前面分析過了靜態聯編時,fun()函式中s所引用的物件被束定到Point類上。而在執行時進行動態聯編將把s的物件引用束定到Rectangle類上。可見,同一個物件引用s,在不同階段被束定的類物件將是不同的。那麼如何來確定是靜態聯編還是動態聯編呢?C++規定動態聯編是在虛擬函式的支援下實現的。如註釋部分所示,當將其宣告為virtual型別的時候,可以採取動態聯編的技術來處理函式fun(). 

從上述分析可以看出靜態聯編和動態聯編也都是屬於多型性的,它們是不同階段對不同實現進行不同的選擇。上例中,實現上是對fun()函式引數的多型性的選擇。該函式的引數是一個類的物件引用,(確切的講應該是一個類的物件的地址或指標型別時)靜態聯編和動態聯編和動態聯編實際上是在選擇它的靜態型別和動態型別。聯編是對這個引用的多型性的選擇。