C++中的靜態聯編和動態聯編介紹(轉)
C++中的靜態聯編和動態聯編介紹(轉)[@more@]聯編是指一個計算機程式自身彼此關聯的過程。按照聯編所進行的階段不同,可分為兩種不同的聯編方法:靜態聯編和動態聯編。
靜態聯編
靜態聯編是指聯編工作出現在編譯連線階段,這種聯編又稱早期聯編,因為這種聯編過程是在程式開始執行之前完成的。
在編譯時所進行的這種聯編又稱靜態束定。在編譯時就解決了程式中的操作呼叫與執行該操作程式碼間的關係,確定這種關係又稱為束定,在編譯時束定又稱靜態束定。下面舉一個靜態聯編的例子。
#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<<
}
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()函式引數的多型性的選擇。該函式的引數是一個類的物件引用,靜態聯編和動態聯編和動態聯編實際上是在選擇它的靜態型別和動態型別。聯編是對這個引用的多型性的選擇。
靜態聯編
靜態聯編是指聯編工作出現在編譯連線階段,這種聯編又稱早期聯編,因為這種聯編過程是在程式開始執行之前完成的。
在編譯時所進行的這種聯編又稱靜態束定。在編譯時就解決了程式中的操作呼叫與執行該操作程式碼間的關係,確定這種關係又稱為束定,在編譯時束定又稱靜態束定。下面舉一個靜態聯編的例子。
#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<<
}
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()函式引數的多型性的選擇。該函式的引數是一個類的物件引用,靜態聯編和動態聯編和動態聯編實際上是在選擇它的靜態型別和動態型別。聯編是對這個引用的多型性的選擇。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10617731/viewspace-957667/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- C++編譯器認為的指標型別(靜態聯編)C++編譯指標型別
- iOS中的動態庫,靜態庫和framework介紹iOSFramework
- apache動態編譯/靜態編譯區別Apache編譯
- C/C++ 編譯器和偵錯程式以及靜態庫、動態庫使用匯總(轉)C++編譯
- Groovy 2.0靜態型別檢查及編譯功能介紹型別編譯
- C++的動態繫結和靜態繫結C++
- Linux下快速靜態編譯Qt以及Qt動態/靜態版本共存Linux編譯QT
- Java中的靜態代理和動態代理Java
- C++建構函式和解構函式呼叫虛擬函式時使用靜態聯編C++函式
- 偽靜態、靜態和動態的區別
- 有關Linux的可執行程式——動態編譯、靜態編譯、readelfLinux行程編譯
- 自關聯和動態group by
- PHP的靜態變數介紹PHP變數
- 關於MNN工程框架編譯出來的靜態庫和動態庫的使用框架編譯
- iOS-靜態庫聯調中的若干問題iOS
- Oracle 靜態引數與動態引數型別介紹Oracle型別
- 靜態編譯Qt5.4.1和Qt WebKit編譯QTWebKit
- JIT-動態編譯與AOT-靜態編譯:java/ java/ JavaScript/Dart亂談編譯JavaScriptDart
- HTML也可以靜態編譯?HTML編譯
- 動態陣列介紹----Delphi (轉)陣列
- 深入理解 C++ 的動態繫結和靜態繫結C++
- 靜態IP的優缺點介紹
- Linux 中的靜態庫和動態庫簡介及生成過程示例Linux
- c++中的靜態成員C++
- 編譯靜態庫的方式使用spdlog和fmt編譯
- 靜態代理和動態代理
- 靜態路由和動態路由路由
- 從fdk_aac編碼器到自動靜態編譯FFmpeg編譯
- linux下靜態庫、動態庫編譯及makefile書寫Linux編譯
- linux成長之路(gcc編譯器、靜態庫、動態庫)LinuxGC編譯
- Android NDK祕籍--編譯靜態庫、呼叫靜態庫Android編譯
- 機器學習的靜態特徵和動態特徵機器學習特徵
- 使用32位64位交叉編碼混淆來打敗靜態和動態分析工具
- DEDE整站動態/靜態轉換
- javascript的靜態方法和例項方法簡單介紹JavaScript
- JSP九大內建物件解析、JSP指令(page、include)、靜態聯編概述JS物件
- 動態VLAN介紹
- Java動態編譯和熱更新Java編譯