C++函數徹底兼容C函數定義的風格,可是也作出了一些改進。一方面,C++函數容許使用缺省參數值和佔位參數;另外一方面,C++提供了重要的函數重載機制;另外,爲了解決C中臭名昭著的宏缺陷問題,C++提供了內聯函數的機制(C99以後也支持這個特性)。從C++11開始,函數定義支持後置返回類型。數組
C++中能夠在函數聲明時爲參數提供一個默認值,當函數調用時若是不提供實參,就使用這個默認值:函數
int func(int x = 0); int main(int argc, char *argv[]) { printf("func() = %d\n", func()); return 0; } int func(int x) { return x; }
注意:默認值只在函數聲明時有效,雖然函數定義中也能夠寫默認值,可是會被函數聲明中的默認值覆蓋。優化
函數默認參數的規則是:指針
在C++中能夠爲函數提供佔位參數。佔位參數只有參數類型聲明,可是沒有參數名;這樣,在函數的實現中是沒法使用這個參數的:code
int func(int) { return 0; } int main(int argc, char *argv[]) { func(1); // 雖然參數無心義,可是仍是要提供來經過編譯。 return 0; }
佔位參數存在的意義是:兼容C語言中可能出現的不規範的寫法,也能夠配合默認值來一塊兒使用。作用域
若是同一個做用域內的幾個函數名稱相同,可是參數列表不一樣,那它們就是重載函數:編譯器
void print(const char *cp); void print(const int *begin, const int *end); void print(const int ia[], size_t size);
函數重載有如下幾個注意點:編譯
注意:返回值類型不一樣不能做爲重載的條件。class
若是函數以值傳遞參數,那麼const
不能構成重載:擴展
void func(int arg); void func(const int arg); // 錯誤:對func的重定義
可是,若是以指針或者引用來傳遞參數,那麼const就能夠構成重載了:
void func1(int *arg); void func1(const int *arg); // 正確:聲明瞭新函數 void func1(const int *const arg); // 正確:聲明瞭新函數 void func2(int &arg); void func2(const int &arg); // 正確:聲明瞭新函數
另外一方面,const成員函數
和非const成員函數
一樣能夠構成函數重載:
class object { public: int func(); const int func() const; // 正確:聲明瞭新函數 };
編譯器會如下面的順序肯定要調用的函數:
頂層const
或者從實參中移除頂層const
const
轉換實現的類型匹配。因爲編譯器須要根據重載規則去挑選與函數指針參數列表一致的函數,而且要嚴格地匹配函數類型與函數指針的類型,所以沒法直接經過函數名獲得重載函數的入口地址:
void func(int); void func(double); int main(int argc, char *argv[]) { void * v = func // 錯誤:沒法經過函數名獲得函數的地址。 void(*pFunc1)(int) = func; // 正確:得到了void func(int)的入口地址。 void(*pFunc2)(double) = func; // 正確:得到了void func(double)的入口地址。 return 0; }
爲了兼容舊有的C語言代碼庫,必須以C語言的編譯規則來編譯函數,所以須要使用以下的方式:
__cplusplus
宏來檢查是否使用了C++extern "C"
來讓編譯器以C語言方式編譯函數#ifdef __cplusplus extern "C" { #endif void func(); // 這個函數將以C語言的方式編譯。 #ifdef __cplusplus } #endif
C++中推薦之內聯函數來代替宏代碼片斷。C++一樣以直接替換代碼塊的方式來處理內聯函數,同時沒有著名的宏缺陷問題。可使用inline
關鍵字來請求編譯器將函數之內聯函數的方式處理 (編譯器可能忽略這個請求):
inline void func() {...}
注意:
內聯函數聲明時inline
必須和函數定義結合在一塊兒,不然編譯器會忽略該請求。
inline
,也可能會被內聯編譯。__forceinline
__attribute__((always_inline))
內聯函數存在一些限制:
C++11提供了函數的後置返回類型,用於兼容自動類型推斷:
auto func() -> void {} // 等價於 void func() {}