解析動態聯編 轉貼

2021-04-01 18:16:36 字數 1431 閱讀 9768

[日期:2005-4-15]

[字型:大 中 小]

文章摘要

多型性是c++最主要的特徵,多型性的實現得益於c++中的動態聯編技術。文章通過對動態聯編的關鍵技術虛函式表進行深入的剖析,解析的動態聯編的過程極其技術要領。

關鍵字

多型性 動態聯編 vtable 虛函式

文章正文

一 從多型性談動態聯編的必要性

在進入主題之前先介紹一下聯編的概念。聯編就是將模組或者函式合併在一起生成可 執行**的處理過程,同時對每個模組或者函式呼叫分配記憶體位址,並且對外部訪問也分配正確的記憶體位址。按照聯編所進行的階段不同,可分為兩種不同的聯編方法:靜態聯編和動態聯編。在編譯階段就將函式實現和函式呼叫關聯起來稱之為靜態聯編,靜態聯編在編譯階段就必須了解所有的函式或模組執行所需要檢測的資訊,它對函式的選擇是基於指向物件的指標(或者引用)的型別。反之在程式執行的時候才進行這種關聯稱之為動態聯編,動態聯編對成員函式的選擇不是基於指標或者引用,而是基於物件型別,不同的物件型別將做出不同的編譯結果。c語言中,所有的聯編都是靜態聯編。c++中一般情況下聯編也是靜態聯編,但是一旦涉及到多型性和虛函式就必須使用動態聯編。

多型性是物件導向的核心,它的最主要的思想就是可以採用多種形式的能力,通過乙個使用者名字或者使用者介面完成不同的實現。通常多型性被簡單的描述為"乙個介面,多個實現。在c++裡面具體的表現為通過基類指標訪問派生類的函式和方法。

下面我們看乙個靜態聯編的例子,這種靜態聯編導致了我們不希望的結果。

//1.cpp

1. #include 2. class shape

在程式編譯期間,由於oneshape為shape型別的,因此它將檢查shape的虛函式表,發現vtable[0]為draw函式的位址,於是翻譯成p->vtable[0]。未來執行期間,p 實際上指向的是circle物件,因此真正呼叫的為circle->vtable[0]處的函式,即circle::draw。同樣對於adjust函式,c++ 編譯器也會去檢查shape的vtable,結果編譯器無法找到adjust函式,因此編譯無法通過。 對於circleshape,因為它是circleshape型別的,因此它將會檢查circle的vtable,得知vtable[2]處為adjust的位址,因此編譯器翻譯成call circleshape->vtable[2],真正執行時候circleshape為circle型別,因此它將繫結circle的vtable[2]處的函式即circle:: adjust()。 就這樣,編譯器借助虛函式表實現了動態聯編的過程,從而使多型的實現有了可能。因此說虛函式表是多型性的幕後功臣一點也不為過。

五 結束語

多型性的實現是乙個非常複雜的過程,上面的討論僅僅是針對簡單繼承而言,即基類只有乙個的情況,對於多重繼承,情況又會有所改變。本文僅是拋磚引玉,希望有興趣的朋友可以一起**。

靜態聯編與動態聯編

在c 中,多型性主要是通過函式過載實現的。過載函式是指程式中對同名函式進行呼叫時,編譯器會根據函式引數的型別和個數,決定該呼叫哪一段函式 來處理這個函式呼叫。這種把函式呼叫與適當的函式 相對應的動作,叫做聯編。聯編分為靜態聯編和動態聯編。在編譯階段決定執行哪個同名的被呼叫函式,稱為靜態聯編。在編譯階...

靜態聯編和動態聯編

聯編是指乙個電腦程式自身彼此關聯 使乙個 源程式經過編譯 連線,成為乙個可執行程式 的過程,在這個聯編過程中,需要確定程式中的操作呼叫 函式呼叫 與執行該操作 函式 的 段之間的對映關係,按照聯編所進行的階段不同,可分為靜態聯編和動態聯編。靜態聯編 呼叫函式和被調函式在程式編譯時,他們在記憶體中的位...

靜態聯編和動態聯編

聯編就是將模組或者函式合併在一起生成可執行 的處理過程,同時對每個模組或者函式呼叫分配記憶體位址,並且對外部訪問也分配正確的記憶體位址,它是電腦程式彼此關聯的過程。按照聯編所進行的階段不同,可分為兩種不同的聯編方法 靜態聯編和動態聯編。靜態聯編是指在編譯階段就將函式實現和函式呼叫關聯起來,因此靜態聯...