靜態聯編與動態聯編之virtual的作用

2021-06-09 11:09:24 字數 2240 閱讀 3693

*************************定義*************************

將乙個呼叫函式連線上正確的被呼叫函式,這個過程就叫做函式的聯編,簡稱聯編。在c++中,一共有兩種聯編的方式:

靜態聯編

#define:靜態聯編是指聯編工作出現在編譯連線階段

#特點:① 靜態聯編就是指被呼叫函式執行呼叫函式之間的關係以及它們在記憶體中的位址在編譯的時候已經確定好了,執行會發生變化

② 由於物件不用對自身進行跟蹤,因此速度浪費比較小,但是靈活性較差。

動態聯編

#define:動態聯編是指在程式執行的時候才進行的聯編工作。

#特點:① 由於編譯程式在編譯階段並不能確切知道將要呼叫的函式,只有在程式執行時才能確定將要呼叫的函式。要確切之道該呼叫的函式,就必須要求聯編工作在程式執行時才能進行。

② 雖然可以追蹤物件,靈活性較強,但是速度浪費嚴重。

*************************virtual的作用*************************

首先,我們來看幾個例子:

//例1 用父類物件的指標指向子類物件

#include using namespace std;

class father

; father(int i)

void print()const

我們先來看一下這個程式的執行結果:

上面這個結果很好理解吧,我就不解釋了。但是如果我們這裡把程式34行的注釋去掉,把33行注釋起來。那麼程式執行的結果就會出現如下的情況:

這個就很奇怪了。我們的初衷是想用乙個父類指標來指向乙個子類物件。但是最後呼叫的print函式卻是父類物件的。這個原因就是因為我們沒有在父類中的print()前面加上關鍵字virtual的原因了。這是因為在函式print()函式前面加上了關鍵字virtual,就表示該函式是有多種形態的,說白了,就是這個print()函式可以被很多物件所擁有,而且各自實現的功能是不一樣的,這樣一來,就是先了多型。總結一下,我們只要在基類的成員函式前面加上virual,那麼就算派生類的物件重新實現了同名函式,編譯器就會自動判斷是哪個物件呼叫了它,然後用該物件的同名函式,而不會採用基類的函式了。程式如下所示:

//例2 用父類物件的指標指向子類物件+virtual

#include using namespace std;

classfather

; father(int i)

virtual void print()const

這樣,我們在程式的第10行上加上了virtual關鍵字。它就將基類的print()函式宣告成了虛函式。這樣一來,我們就可以呼叫子類的print()函式了,上圖發真相!

virtual與聯編之間的關係*************************

相對於例1來講,在這裡面呼叫的關係就是靜態聯編,因為在程式的編譯階段就已經把物件和它們所指向的函式緊緊地聯絡在一起了,執行的時候自然就不會有任何改變。而對於例2來講,由於在父類的print()函式前面加上了關鍵字virtual,那麼這個時候父類中的print()函式就變成了虛函式,虛函式就可以實現執行時的動態聯編。這是因為virtual會讓編譯器自動地區尋找與之對應的物件,所以輸出才會於紅框所示,「son's age is 22」。

特別注意一點!!!只有在使用指標或者是引用的時候,才能夠實現動態聯編。

靜態聯編與動態聯編

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

動態聯編與靜態聯編

首先,聯編是指乙個電腦程式的不同部分彼此關聯的過程。靜態聯編是指聯編工作在編譯階段完成的,這種聯編過程是在程式執行之前完成的,又稱為早期聯編。要實現靜態聯編,在編譯階段就必須確定程式中的操作呼叫 如函式呼叫 與執行該操作 間的關係,確定這種關係稱為束定,在編譯時的束定稱為靜態束定。靜態聯編對函式的選...

動態聯編與靜態聯編

include using namespace std class base 輸出為 f1 of base destructor base f1 of derive destructor base 說明 只要將基類的函式設定為虛函式,那麼所有覆蓋它的子類的函式也都是虛函式,而不需要再使用virtua...