【C++入门】Cyber骇客的同名异梦——【C++重载函数】(与C的函数差异)

⚡ CYBER_PROFILE ⚡
/// SYSTEM READY ///


WARNING \]: DETECTING HIGH ENERGY **🌊 🌉 🌊 心手合一 · 水到渠成** ![分隔符](https://i-blog.csdnimg.cn/direct/60a3de2294e9439abad47378e657b337.gif) |------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------| | **\>\>\> ACCESS TERMINAL \<\<\<** || | [**\[ 🦾 作者主页 \]**](https://blog.csdn.net/fengtinghuqu520?spm=1000.2115.3001.5343) | [**\[ 🔥 C语言核心 \]**](https://blog.csdn.net/fengtinghuqu520/category_12955956.html) | | [**\[ 💾 编程百度 \]**](https://blog.csdn.net/fengtinghuqu520/category_13083835.html) | [**\[ 📡 代码仓库 \]**](https://blog.csdn.net/fengtinghuqu520/article/details/147275999?spm=1001.2014.3001.5502) | --------------------------------------- Running Process: 100% \| Latency: 0ms *** ** * ** *** #### 索引与导读 * [📘1)核心定义](#📘1)核心定义) * [📘2)如何构成重载](#📘2)如何构成重载) * * [2.1 参数类型不同](#2.1 参数类型不同) * [2.2 参数个数不同](#2.2 参数个数不同) * [2.3 参数顺序不同](#2.3 参数顺序不同) * [📘3)常见误区与陷阱](#📘3)常见误区与陷阱) * * [3.1)返回值类型不同 不构成重载](#3.1)返回值类型不同 不构成重载) * [3.2)缺省参数导致的二义性](#3.2)缺省参数导致的二义性) * [3.3)类型别名](#3.3)类型别名) * [📘4)为何C语言不支持函数重载?](#📘4)为何C语言不支持函数重载?) * [函数重载代码示例](#函数重载代码示例) * [💻结尾--- 核心连接协议](#💻结尾— 核心连接协议) ## 📘1)核心定义 在自然语言中,一个词在不同语境下可能有不同的含义(一词多义)。在` C++ 中`,**函数重载** 允许在**同一作用域** 中声明多个**名称相同** 但**形参列表不同**的函数。 我们在调用函数时,编译器会根据传递的实参类型,自动推演并匹配最合适的那个函数版本。这属于 `C++` **静态多态(Static Polymorphism)** 的一种体现,即在编译期间就确定了具体的函数调用 *** ** * ** *** ## 📘2)如何构成重载 🚩要让两个同名函数共存,它们的**函数签名** 必须不同 * 主要体现在以下三个维度: ### 2.1 参数类型不同 ```cpp #include using namespace std; void print(int i) { cout << "Int: " << i << endl; } void print(double d) { cout << "Double: " << d << endl; } int main() { print(10); // 匹配 print(int) print(3.14); // 匹配 print(double) return 0; } ``` ### 2.2 参数个数不同 ```cpp void func(int a) { cout << "One parameter" << endl; } void func(int a, int b) { cout << "Two parameters" << endl; } ``` ### 2.3 参数顺序不同 ```cpp void func(int a, char b); // 版本 1 void func(char a, int b); // 版本 2,构成重载 ``` *** ** * ** *** ## 📘3)常见误区与陷阱 ### 3.1)返回值类型不同 不构成重载 ```cpp int add(int a, int b); void add(int a, int b); // ❌ 错误:编译报错 ``` **原因:** 在调用函数时(例如 `add(1, 2);`),调用者可以选择忽略返回值。此时编译器无法根据上下文判断应该调用哪一个函数,从而产生二义性 *** ** * ** *** ### 3.2)缺省参数导致的二义性 虽然两个函数参数个数不同可以重载,但如果结合了默认参数,可能会翻车 ```cpp void func(int a, int b = 10) { cout << "Version 1" << endl; } void func(int a) { cout << "Version 2" << endl; } int main() { // func(10, 20); // OK, 调用 Version 1 // func(10); // ❌ 错误:二义性! // 编译器OS:你是想调用 Version 2,还是想调用带有默认参数的 Version 1?我太难了。 return 0; } ``` *** ** * ** *** ### 3.3)类型别名 ```cpp typedef int Integer; void func(int a); void func(Integer a); // ❌ 错误:重定义 ``` **原因:** `Integer` 本质上就是 `int`,编译器眼里它们是完全一样的东西 *** ** * ** *** ## 📘4)为何C语言不支持函数重载? * **C 语言的处理方式** **`C` 语言编译器在编译代码时,生成的符号表中,函数名就是源代码中的名字** **源码:** `void add(int a, int b)` **符号表:** `_add` 如果在`C`语言中写两个`add`函数,符号表中就会有两个` _add`,链接器在链接时就会报错:`"Multiple definition of symbol"`(符号重定义) * **C++ 的"名称修饰"** **`C++` 为了支持重载,引入了名称修饰机制** *编译器会根据函数的**参数类型** 、**参数个数** 、**参数顺序**等信息,对函数名进行"加密"和修饰,生成一个全局唯一的符号名* > **以 GCC 编译器为例(不同编译器规则不同):** > ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/0dc7f0b7c8874541b7b64bbf2cd058f4.png) *** ** * ** *** **结论:** 虽然我们在代码里看到的都是` func`,但在编译器的眼里,它们分别是` _Z4funci`、`_Z4funcd` 和 `_Z4funcii` 由于底层的符号名不同,链接器自然就能区分它们,从而实现了重载 *** ** * ** *** ## 函数重载代码示例 ```cpp #include using namespace std; // 1. 参数类型不同 int Add(int left, int right) { cout << "int Add(int left, int right)" << endl; return left + right; } double Add(double left, double right) { cout << "double Add(double left, double right)" << endl; return left + right; } // 2. 参数个数不同 void f() { cout << "f()" << endl; } void f(int a) { cout << "f(int a)" << endl; } // 3. 参数类型顺序不同 void f(int a, char b) { cout << "f(int a, char b)" << endl; } void f(char b, int a) { cout << "f(char b, int a)" << endl; } // 返回值不同不能作为重载条件,因为调用时也无法区分 //void fxx() //{} // //int fxx() //{ // return 0; //} // 下面两个函数构成重载 // f() 但是调用时,会报错,存在歧义,编译器不知道调用谁 void f1() { cout << "f()" << endl; } void f1(int a = 10) { cout << "f(int a)" << endl; } int main() { Add(10, 20); Add(10.1, 20.2); f(); f(10); f(10, 'a'); f('a', 10); return 0; } ``` *** ** * ** *** ## 💻结尾--- 核心连接协议 **警告:** 🌠🌠正在接入底层技术矩阵。如果你已成功破解学习中的逻辑断层,请执行以下指令序列以同步数据:🌠🌠 *** ** * ** *** **【📡】 建立深度链接:** **关注**本终端。在赛博丛林中深耕底层架构,从原始代码到进阶协议,同步见证每一次系统升级。 **【⚡】 能量过载分发:** 执行**点赞**操作。通过高带宽分发,让优质模组在信息流中高亮显示,赋予知识跨维度的传播力。 **【💾】 离线缓存核心:** 将本页加入**收藏**。把这些高频实战逻辑存入你的离线存储器,在遭遇系统崩溃或需要离线检索时,实现瞬时读取。 **【💬】 协议加密解密:** 在**评论区**留下你的散列码。分享你曾遭遇的代码冲突或系统漏洞(那些年踩过的坑),通过交互式编译共同绕过技术陷阱。 **【🛰️】 信号频率投票:** 通过**投票**发射你的选择。你的每一次点击都在重新定义矩阵的进化方向,决定下一个被全量拆解的技术节点。 *** ** * ** *** ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/57b03915c54b43a7a03fa92dbbfe57c3.gif) ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/0905dc972de8414bb602715de3f866ee.gif)

相关推荐
charlie1145141912 小时前
现代嵌入式C++教程:if constexpr——把编译期分支写得像写注释 —— 工程味实战指南
开发语言·c++·笔记·学习·嵌入式·现代c++
冰暮流星2 小时前
javascript如何转换为字符串与布尔型
java·开发语言·javascript
LIZhang20162 小时前
c++ 转化句柄,解决多线程安全释放问题
开发语言·c++
youqingyike2 小时前
Qt 中 QWidget 调用setLayout 后不显示
开发语言·c++·qt
_OP_CHEN2 小时前
【从零开始的Qt开发指南】(二十二)Qt 音视频开发宝典:从音频播放到视频播放器的实战全攻略
开发语言·c++·qt·音视频·前端开发·客户端开发·gui开发
FAFU_kyp2 小时前
Rust 字符串与切片
开发语言·后端·rust
oioihoii2 小时前
从C++到C#的转型完全指南
开发语言·c++·c#
Ashley_Amanda2 小时前
Python入门知识点梳理
开发语言·windows·python
区区一散修2 小时前
Java进阶 6. 集合
java·开发语言