執行c ++程式時,它從main()的頂部開始按順序執行。遇到函式呼叫時,執行點會跳轉到被呼叫函式的開頭。cpu如何知道這樣做?
編譯程式時,編譯器會將c ++程式中的每個語句轉換為一行或多行機器語言。每行機器語言都有自己獨特的順序位址。這與函式沒什麼不同 - 當遇到函式時,它被轉換成機器語言並給出下乙個可用的位址。因此,每個功能都以唯一的位址結束。
繫結是指用於將識別符號(例如變數和函式名稱)轉換為位址的過程。雖然繫結用於變數和函式,但在本課中我們將重點關注函式繫結。
早期繫結
編譯器遇到的大多數函式呼叫都是直接函式呼叫。直接函式呼叫是直接呼叫函式的語句。例如:
#include void printvalue(int value)
int main()
可以使用稱為早期繫結的過程來解析直接函式呼叫。 早期繫結(也稱為靜態繫結)意味著編譯器(或鏈結器)能夠直接將識別符號名稱(例如函式或變數名稱)與機器位址相關聯。請記住,所有函式都有唯一的位址。因此,當編譯器(或鏈結器)遇到函式呼叫時,它會用乙個機器語言指令替換函式呼叫,該指令告訴cpu跳轉到函式的位址。
我們來看乙個使用早期繫結的簡單計算器程式:
#include int add(int x, int y)
int subtract(int x, int y)
int multiply(int x, int y)
int main()
while (op < 0 || op > 2);
int result = 0;
switch (op)
std::cout << "the answer is: " << result << std::endl;
return 0;
}
因為add(),subtract()和multiply()都是直接函式呼叫,所以編譯器將使用早期繫結來解析add(),subtract()和multiply()函式呼叫。編譯器將使用一條指令替換add()函式呼叫,該指令告訴cpu跳轉到add()函式的位址。對於subtract()和multiply()也是如此。
後期繫結
在某些程式中,直到執行時(程式執行時)才能知道將呼叫哪個函式。這稱為後期繫結(或動態繫結)。在c ++中,獲得後期繫結的一種方法是使用函式指標。為了簡要回顧一下函式指標,函式指標是一種指向函式而不是變數的指標。可以通過在指標上使用函式呼叫運算子來呼叫函式指標指向的函式。
例如,以下**呼叫add()函式:
#include int add(int x, int y)
int main()
通過函式指標呼叫函式也稱為間接函式呼叫。以下計算器程式在函式上與上面的計算器示例相同,只是它使用函式指標而不是直接函式呼叫:
#include int add(int x, int y)
int subtract(int x, int y)
int multiply(int x, int y)
int main()
while (op < 0 || op > 2);
// 建立乙個名為pfcn的函式指標(是的,語法很難看)
int (*pfcn)(int, int) = nullptr;
// 將pfcn設定為指向使用者選擇的函式
switch (op)
// 使用x和y作為引數呼叫pfcn指向的函式
// 這使用後期繫結
std::cout << "the answer is: " << pfcn(x, y) << std::endl;
return 0;
}
在這個例子中,我們不是直接呼叫add(),subtract()或multiply()函式,而是將pfcn設定為指向我們希望呼叫的函式。然後我們通過指標呼叫函式。編譯器無法使用早期繫結來解析函式呼叫pfcn(x, y),因為它無法分辨編譯時pfcn將指向哪個函式!
後期繫結的效率略低,因為它涉及額外的間接級別。通過早期繫結,cpu可以直接跳轉到函式的位址。使用後期繫結,程式必須讀取指標中儲存的位址,然後跳轉到該位址。這涉及乙個額外的步驟,使其稍慢。但是,後期繫結的優點是它比早期繫結更靈活,因為關於呼叫哪個函式的決定不需要在執行時進行。
在下一課中,我們將了解如何使用後期繫結來實現虛擬功能。
C 基礎教程物件導向(學習筆記5(2))
在編寫具有多個建構函式的類 大多數建構函式 時,必須為每個建構函式中的所有成員指定預設值會導致冗餘 如果更新成員的預設值,則需要觸控每個建構函式。從c 11開始,可以直接為普通類成員變數 不使用static關鍵字的變數 提供預設初始化值 class rectangle void print int ...
C 基礎教程物件導向(學習筆記(23))
過載一元運算子 與您目前看到的運算子不同,正 負 和邏輯非 運算子都是一元運算子,這意味著它們只能在乙個運算元上執行。因為它們僅對它們所應用的物件進行操作,所以通常將一元運算子過載實現為成員函式。所有三個運算元都以相同的方式實現。讓我們看一下我們如何在前面的例子中使用的cents類上實現operat...
C 基礎教程物件導向(學習筆記(24))
過載比較運算子相對簡單,因為它們遵循我們在過載其他運算子時看到的相同模式。因為比較運算子都是不修改左運算元的二元運算子,所以我們將使過載的比較運算子宣告為友元函式。這是乙個帶有過載運算子 和operator!的car類的示例。include include class car friend bool...