函數重載趕上函數指針編程
將重載函數名賦值給函數指針時函數
- 根據重載規則挑選與函數指針參數列表一致的候選者
- 嚴格匹配候選者的函數類型與函數指針的函數類型
#include <stdio.h> #include <string.h> int func(int x) { return x; } int func(int a, int b) { return a + b; } int func(const char* s) { return strlen(s); } typedef int(*PFUNC)(int c); int main(int argc, char* argv[]) { int c = 0; PFUNC p = func; c = p(1); printf("c = %d\n", c); return 0; }
輸出: c = 1
注意指針
- 函數重載必然發生在同一個做用域
- 編譯器須要用參數列表或函數類型進行函數選擇
- 沒法直接經過函數名獲得重載函數的入口
應該怎樣得到某一個重載函數的地址呢?code
#include <stdio.h> int add(int a, int b) // int(int, int) { return a + b; } int add(int a, int b, int c) // int(int, int, int) { return a + b + c; } int main() { printf("%p\n", (int(*)(int, int))add); // 經過類型轉換獲得函數指針 printf("%p\n", (int(*)(int, int, int))add); return 0; }
- 實際工程中 C++ 和 C 代碼相互調用是不可避免的(尤爲在已經存在的C源碼或C庫)
- C++ 編譯器可以兼容 C 語言的編譯方式
- C++ 編譯器會優先使用 C++ 編譯的方式
- extern 關鍵字能強制讓 C++ 編譯器進行 C 方式的編譯
extern "C" { // do C-style compilation here }
add.h作用域
int add(int a, int b);
add.c編譯器
#include "add.h" int add(int a, int b) { return a + b; }
main_1.cpp源碼
#include <stdio.h> #include "add.h" int main() { int c = add(1, 2); printf("c = %d\n", c); return 0; }
gcc -c add.c -o add.oo g++ add.h add.oo main.cpp 輸出: main_1.cpp:(.text+0x19): undefined reference to `add(int, int)' collect2: ld returned 1 exit status
main_2.cstring
#include <stdio.h> extern "C" { #include "add.h" } int main() { int c = add(1, 2); printf("c = %d\n", c); return 0; }
輸出: c = 3 分析:【不一樣的編譯方式致使不一樣的編譯結果】 gcc 編譯 add.c add.h 生成 add.oo 中的符號表 00000000 T add g++ 編譯 add.c add.h 生成 add.oo 中的符號表 00000000 T _Z3addii U __gxx_personality_v0
- __cplusplus 是 C++ 編譯器內置的標準宏定義
- __cplusplus 的意義:確保 C 代碼以統一的 C 方式被編譯成目標文件
#ifdef __cpusplus extern "C" { #endif // C-Style Compilation #ifdef __cpluscplus } #endif
add.hit
int add(int a, int b);
add.cio
#include "add.h" int add(int a, int b) { return a + b; }
main.c
#include <stdio.h> #ifdef __cplusplus extern "C" { #endif #include "add.h" #ifdef __cplusplus } #endif int main() { int c = add(1, 2); printf("c = %d\n", c); return 0; }
輸出: c = 3
- C++ 編譯器不能以 C 的方式編譯重載函數
- 編譯方式決定函數名被編譯後的目標名
- C++ 編譯方式將函數名和參數列表編譯成目標名
- C 編譯方式只將函數名做爲目標名進行編譯
- 函數重載是 C++ 對 C 的一個重要升級
- 函數重載經過函數參數列表區分不一樣的同名函數
- extern 關鍵字可以實現 C 和 C++ 的相互調用
- 編譯方式決定符號表中的函數名的最終目標名
以上內容參考狄泰軟件學院系列課程,請你們保護原創!