網站首頁 編程語言 正文
1 函數重載的定義
函數重載:使用同一個函數名定義不同的函數。從本質上來看,就是互相獨立的不同函數,每一個函數類型不同。因此,函數重載是由函數名和參數列表決定的。
注意:函數返回值不能作為函數重載的重要依據!
2 構成函數重載的條件
當滿足以下三個條件之一時,便可以構成函數重載
函數參數個數不同
// 函數類型:void(int) void Demo(int x) { printf("x = %d\r\n", x); } // 函數類型:void(int, int) void Demo(int x, int y) { printf("x = %d\r\n", x); printf("y = %d\r\n", y); } // 函數類型:void(int, int, int) void Demo(int x, int y, int z) { printf("x = %d\r\n", x); printf("y = %d\r\n", y); printf("z = %d\r\n", z); }
函數參數類型不同
void Demo(int x) { printf("x = %d\r\n", x); } void Demo(char x) { printf("x = %c\r\n", x); }
函數參數順序不同
void Demo(char c, int x) { printf("x = %d\r\n", x); printf("c = %c\r\n", c); } void Demo(int x, char c) { printf("x = %d\r\n", x); printf("c = %c\r\n", c); }
但是,如果函數的參數類型均相同,僅僅順序不同同樣會出錯,如下所示的代碼:
void Demo(int x, int y, int z) { printf("x = %d\r\n", x); printf("y = %d\r\n", y); printf("z = %d\r\n", z); } void Demo(int y, int x, int z) { printf("x = %d\r\n", x); printf("y = %d\r\n", y); printf("z = %d\r\n", z); }
3 編譯器調用重載函數的準則
編譯器編譯代碼的流程:
將所有同名函數作為候選者
嘗試尋找可行的候選函數
- 精確匹配實參
- 通過默認參數匹配實參
- 通過默認類型轉換匹配實參
匹配成功
如果編譯失敗的話,有如下兩種情況:
- 找到的候選函數不唯一,出現二義性,失敗
- 無法匹配所有候選者,函數未定義,失敗
4 函數重載的注意事項
4.1 避開重載帶有指定默認值參數的函數
在我們使用函數重載的過程,要注意避開重載帶有指定默認值參數的函數。否則在使用的過程中,會出現二義性,導致編譯失敗。如下代碼所示的錯誤示例:
void Demo(int x, int y) { printf("x = %d\r\n", x); printf("y = %d\r\n", y); } void Demo(int x, int y, int z = 0) { printf("x = %d\r\n", x); printf("y = %d\r\n", y); printf("z = %d\r\n", z); } int main() { Demo(1, 2); return 0; }
當對重載函數進行調用時 Demo(1, 2)
,編譯器是無法分辨我們到底是使用 void Demo(int x, int y)
函數,還是使用 void Demo(int x, int y, int z = 0)
函數,因此無法編譯通過。
4.2 注意函數重載遇上函數指針
重載函數的名稱賦值給函數指針后,當對函數指針進行調用時,將根據下面的方式進行函數匹配
- 首先,根據重載規則挑選與函數指針參數列表一致的候選者
- 然后,根據候選者的函數類型與函數指針的函數類型進行匹配
通過如下代碼所示的示例進行解釋:
typedef int(*PDemo)(int i); // Demo1 int Demo(int x) { return x; } // Demo2 int Demo(int x, int y) { return x * y; } // Demo3 int Demo(const char* c) { return strlen(c); } int main() { int i = 0; PDemo pd = Demo; // 一個參數,因此不是Demo1就是Demo3 // pd的函數類型是int(int)與Demo1相同,因此就是Demo1 i = pd(1); return 0; }
如果將上述示例中函數指針的返回類型由 int
更改成 double
,仍通過 pd(1)
進行調用的話,該程序將不能被編譯過,因為沒有與之匹配的重載函數。
- 參數列表沒有問題
- 函數返回值類型有問題,因為函數類型包含函數的返回值類型
4.3 C++編譯器不能以 C 的方式編譯重載函數
由于 C++ 編譯器將函數名和參數列表編譯成目標名,C 編譯器將函數名編譯成目標名,這樣 C 編譯器編譯后的重載函數的目標名一致,于是便無法實現重載函數的功能。
原文鏈接:https://blog.csdn.net/weixin_44916154/article/details/124933542
相關推薦
- 2022-09-04 C#使用async和await實現異步編程_C#教程
- 2022-07-02 webpack分離公共模塊失敗
- 2022-03-22 ASP.NET Core中如何使用Dapper
- 2022-08-02 Android開發自定義雙向SeekBar拖動條控件_Android
- 2024-07-15 bootspring第三方資源配置管理
- 2022-07-28 Python自動化實戰之接口請求的實現_python
- 2022-12-04 C#實現Oracle批量寫入數據的方法詳解_C#教程
- 2022-04-29 通過C#程序操作Config文件_C#教程
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支