第9课 - 函数重载分析(下)
第9課 - 函數重載分析(下)
1. 重載與指針
1.1 下面的函數指針將保存哪個函數的地址?
1.2 函數重載遇上函數指針
? 將重載函數名賦值給函數指針時:
(1)根據重載規則挑選與函數指針參數列表一致的候選者
(2)嚴格匹配候選者的函數類型與函數指針的函數類型 (這里不僅需要匹配參數類型,還需要匹配返回值的類型,不然編譯會出錯!!!)
1 #include <stdio.h> 2 #include <string.h> 3 4 int func(int a) 5 { 6 return a; 7 } 8 9 int func(int a, int b) 10 { 11 return a + b; 12 } 13 14 int func(const char *s) 15 { 16 return strlen(s); 17 } 18 19 typedef int (*pFunc)(int); // 注意typedef后面的分號 20 21 int main(void) 22 { 23 int c = 0; 24 pFunc p = func; 25 26 c = p(1); // 根據pFunc指針的類型選擇對應的重載函數 27 28 printf("c = %d\n", c); 29 30 return 0; 31 } 函數重載 VS 函數指針1.3 注意事項
(1)函數重載必然發生在同一個作用域中
(2)編譯器需要用參數列表或函數類型進行函數選擇 【函數指針和參數的間接關系,函數指針中包含了返回值和參數類型的信息】
(3)無法直接通過函數名得到重載函數的入口地址
2. C++ 和 C 的相互調用
2.1 C++ 和 C 的相互調用
(1)實際工程中C++ 和C 代碼相互調用是不可避免的
(2)C++?編譯器能夠兼容C 語言的編譯方式
(3)C++?編譯器會優先使用C++ 編譯的方式
(4)extern?關鍵字能強制讓C++ 編譯器進行C 方式的編譯
【編程實驗】C++ 調用C 函數
1 int add(int a, int b); add.h 1 #include "add.h" 2 3 //該文件的編譯,得到目標文件add.o 4 //gcc -c add.c 5 6 int add(int a, int b) 7 { 8 return a + b; 9 } add.c 1 #include <stdio.h> 2 3 //該文件的編譯 4 //g++ main.cpp add.o 5 6 #ifdef __cplusplus 7 extern "C" { 8 #endif 9 10 //C++中以C的方式編譯:將add的函數名就是目標名 11 #include "add.h" 12 13 #ifdef __cplusplus 14 } 15 #endif 16 17 int main() 18 { 19 int c = add(1, 2); 20 21 printf("c = %d\n", c); //3 22 23 return 0; 24 } main.cpp2.2?如何保證一段C代碼只會以C的方式被編譯?
(1)__cplusplus 是 C++ 編譯器內置的標準宏定義
(2)__cplusplus 的意義:確保C代碼以統一的C方式被編譯成目標文件
【編程實驗】C 調用 C++ 函數?(其中的C++ 函數由gcc 編譯)
1 //該文件的編譯,得到目標文件add.o 2 //g++ -c add.c 3 4 #ifdef __cplusplus 5 extern "C" { 6 #endif 7 8 //C++中以C的方式編譯:add的函數名就是目標名 9 int add(int a, int b); 10 11 #ifdef __cplusplus 12 } 13 #endif add.h 1 #include "add.h" 2 3 //該文件的編譯,得到目標文件add.o 4 //g++ -c add.c 5 6 #ifdef __cplusplus 7 extern "C" { 8 #endif 9 10 //C++中以C的方式編譯:add的函數名就是目標名 11 int add(int a, int b) 12 { 13 return a + b; 14 } 15 16 #ifdef __cplusplus 17 } 18 #endif add.cpp 1 #include <stdio.h> 2 #include "add.h" 3 //編譯方式: 4 //gcc main.c add.o 5 int main() 6 { 7 int c = add(1, 2); 8 9 printf("c = %d\n", c); //3 10 11 return 0; 12 } main.c【編程實驗】C 調用 C++ 函數?(其中的C++ 函數由g++ 編譯)
?、偌僭O別人提供了編譯好的cpp的頭文件和.o目標文件,但其中的函數是以C++方式編譯的,很明顯函數名是用C++方式命名的。我們的C文件里不方便使用這個的函數名。
?、诮鉀Q方案:做一個C++的封裝層,對其中的函數進行一個封裝,然后再用extern? "c"編譯這些封裝層中的函數,最后就可以在C文件中使用了。
?
★ 其他人編寫的C++代碼,其中的函數名是用C++方式編譯的,但只提供的.h和.o文件
1 int add(int a, int b); add.h 1 #include "add.h" 2 3 //編譯命令:g++ -c add.cpp 4 5 int add(int a, int b) 6 { 7 return a + b; 8 } add.cpp 1 int addEx(int a, int b); addEx.h 1 #include "add.h" 2 3 //編譯命令: 4 //g++ -c addEx.cpp 5 6 extern "C" int addEx(int a,int b) 7 { 8 return add(a, b); 9 } addEx.cpp 1 #include <stdio.h> 2 #include "addEx.h" 3 //編譯命令: 4 //gcc main.c addEx.0 add.o 5 6 int main() 7 { 8 int c = addEx(1, 2); 9 10 printf("c = %d\n", c); //3 11 12 return 0; 13 } main.c主文件2.3 注意事項
(1)C++ 編譯器不能以C 的方式編譯重載函數,即如果在extern ?"C"塊里有兩個同名的函數里,則會編譯失敗。
(2)編譯方式決定函數名被編譯后的目標名
ⅰ:C++ 編譯方式將函數名和參數列表編譯成目標名
ⅱ:C 編譯方式只將函數名作為目標名進行編譯
3. 小結
(1)函數重載是C++ 對 C 的一個重要升級
(2)函數重載通過函數參數列表區分不同的同名參數
(3)extern關鍵字能夠實現C 和 C++ 的相互調用
(4)編譯方式決定符號表中的函數名的最終目標名
?
轉載于:https://www.cnblogs.com/shiwenjie/p/7169678.html
總結
以上是生活随笔為你收集整理的第9课 - 函数重载分析(下)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 梦到已故的狗狗还活着什么预兆
- 下一篇: 垂直和水平居中方法小结