函式過載還有乙個別名叫函式多型,其實我個人感覺函式多型這個名字更好理解更恰當一些。
函式多型是c++在c語言基礎上的新特性,它可以讓我們程式設計客棧使用多個同名函式。當然這些同名函式的引數是要有區別的,我們在函式呼叫的時候,編譯器會自動根據我們傳入的引數,從多個同名函式當中找到我們呼叫的那乙個。和物件導向裡的多型的概念很接近。
我們在定義函式的時候,編譯器只會檢視引數的數目和型別,而不會理會引數的名稱。只要引數的數量以及型別不完全相同,就會被認為是不同的函式。
比如:void print(const char *str, int width);
void print(double d, int width);
void print(long l, int width);
void print(int i, int width);
void print(const char *str);
上面列舉的5個函式它們彼此之間的函式引數的數量和型別都不完全相同,因此會被視為是不同的函式。我們在使用的時候編譯器會根據我們傳入的引數使用對應的函式。
print('pancakes', 15); // use 1
print('pancakes'); // use 5
print(1999.0, 10); // use 2
print(199, 23); // use 4
print(199l, 15); // use 3
這當然沒有問題,如果我們這樣使用呢:
unsigned year = 2021;
print(year, 6);
我們可以發現我們這裡傳入的引數型別是unsigned int,它不和任何函式的入參型別匹配。這個時候編譯器並不會放棄,而是會嘗試使用標準型別轉換強制進行匹配。但問題來了,我們有三個版本的函式的第乙個入參是數字型別,於是就有了三種變數轉換的方式。這個時候c++將拒絕這種函式呼叫,進行報錯。
同樣,一些看起來彼此不同的引數也是不能共存的,比如:
double cube(double x);
double cube(double &x);
看起來乙個是值傳遞乙個是引用傳遞,但是對於編譯器來說,顯然它是無法分辨我們究竟要呼叫哪乙個的。
還有一點需要注意,就是const修飾符。
void dribble(char *bits); //1
void dribble(const char *bits); //2
dribble函式有兩個型別,乙個用於const指標,乙個用於常規指標,編譯器將會根據實參是否為const來決定使用哪個函式。因為將非const值賦給const變數是合法的,但反之是非法的。
另外,編譯器區分函式是根據函式的引數數量和型別並不是根據函式的返回值。所以下面的兩個宣告是有問題的:
long gronk(int n, float m);
double gronk(int n, float m);
因為它們的引數數量以及型別都是一樣的,儘管返回型別不同,但編譯器依然無法區分。
這個問題經常在面試當**現,面試官會故意挖坑問你,函式過載的依據是什麼。如果兩個函式的返回型別不同,但是引數一樣,能不能過載。很多同學對過載的概念記憶不是非常深刻,面試的時候腦子一熱就中招了,所以一定要注意。
模板函式的詳情介紹
0.如何編寫乙個高效的加法函式?1.什麼是模板函式?2.模板函式怎麼寫?3.模板如何進行例項化?隱式例項化?顯式例項化?4.什麼是引數推演?5.模板函式如何編譯?6.模板函式的模板引數列表?型別引數?非型別引數?7.模板函式的過載?8.什麼是模板的特化?0.如何編寫乙個高效的加法函式?學完c語言,若...
C 內聯函式詳情
內聯函式是c 當中為了提高程式執行效率的設計,老實講我沒有在其他語言當中看到類似的設計。它和常規函式之間的主要區別不在pemnakfx於編寫的方式,而是在於c 編譯器會將內聯函式組合到程式當中執行。要解釋這個過程會稍稍有些複雜,我們需要從編譯的過程說起。對於編譯型語言而言,編譯器做的事情是把人類寫出...
C 函式過載,引用,內聯函式的介紹
什麼是函式過載呢?函式過載是函式的一種特殊情況,在同一作用域中宣告幾個功能類似的同名函式,這些函式的形參列表 型別,個數,順序 必須不同。知道了函式過載的概念,那麼我們就要知道c語言的編譯的時候是如何處理函式的,首先我們要編譯c風格的 我們需要讓某些函式以c的方式編譯,在函式前面加上 extern ...