当前位置: 首页 > news >正文

【C++入门学习指南】:函数重载提升代码清晰度与灵活性

个人头像
🎥 屿小夏 : 个人主页
🔥个人专栏 : C++入门到进阶
🌄 莫道桑榆晚,为霞尚满天!

文章目录

  • 📑前言
  • 一、函数重载
    • 1.1 函数重载的概念
    • 1.2 函数重载的作用
    • 1.3 C++支持函数重载的原理
    • 1.4 扩展
  • 🌤️ 全篇总结

📑前言

函数重载是C++中非常重要的概念,它允许在同一作用域中声明多个同名函数,但这些函数的参数列表必须不同。通过函数重载,可以提高代码的可读性和可维护性,简化函数调用,并提供更多的灵活性。本文将深入探讨函数重载的概念、作用以及C++支持函数重载的原理,帮助读者更好地理解和应用这一重要的编程特性。

一、函数重载

1.1 函数重载的概念

函数重载是函数的一种特殊情况:

C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同,常用来处理实现功能类似数据类型不同的问题。

#include<iostream>
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;
}
int main()
{Add(10, 20);Add(10.1, 20.2);f();f(10);f(10, 'a');f('a', 10);return 0;
}

1.2 函数重载的作用

  1. 提高代码的可读性和可维护性:通过使用相同的函数名来表示一组相关的功能,可以使代码更加清晰和易于理解。
  2. 简化函数调用:不同的参数列表可以根据不同的情况选择合适的函数进行调用,避免了编写大量的条件判断语句。
  3. 提供更多的灵活性:通过函数重载,可以根据需要提供多种不同的函数实现,满足不同的需求。

1.3 C++支持函数重载的原理

C++支持函数重载,但是C语言不支持函数重载,这是为什么呢?
在C/C++中,一个程序要运行起来,需要经历以下几个阶段:预处理、编译、汇编、链接 。

image-20231023191250878

image-20231023191326892

  1. 实际项目通常是由多个头文件和多个源文件构成,当前a.cpp中调用了b.cpp中定义的Add函数时,编译后链接前,a.o的目标文件中没有Add的函数地址,因为Add是在b.cpp中定义的,所以Add的地址在b.o中。那么怎么办呢?

  2. 链接阶段就是专门处理这种问题,链接器看到a.o调用Add,但是没有Add的地址,就会到b.o的符号表中找Add的地址,然后链接到一起。

  3. 链接时,面对Add函数,链接接器会使用哪个名字去找呢?这里每个编译器都有自己的函数名修饰规则。

Windows下vs修饰规则过于复杂,Linux下g++修饰规则简单易懂,下面使用g++演示这个修饰后的名字。

C语言编译后:函数名字的修饰没有发生改变。

image-20231023191604289

C++编译后:函数名字的修饰发生改变,编译器将函数参数类型信息添加到修改后的名字中。

image-20231023191722503

以上我们可以看出gcc的函数修饰后名字不变。而g++的函数修饰后变成【_Z+函数长度+函数名+类型首字母】。

这里就理解了C语言没办法支持重载,因为同名函数没办法区分。而C++是通过函数修饰规则来区分,只要参数不同,修饰出来的名字就不一样,就支持了重载。

如果两个函数函数名和参数是一样的,返回值不同是不构成重载的,因为调用时编译器没办法区分。

1.4 扩展

image-20240101171235979

windows下vs编译器对函数名字修饰规则相对复杂难懂,但道理都是类似的,这里就不做细致的研究了。

关于对C/C++函数调用约定和名字修饰规则,C/C++的调用约定 里面有对vs下函数名修饰规则讲解。

有兴趣好奇的小伙伴可以看看哦~

🌤️ 全篇总结

函数重载是C++编程中的重要概念,掌握了函数重载,可以使代码更加清晰易懂,提高代码的灵活性和可维护性。

image-20231229145151002

相关文章:

  • MTK8365安卓核心板_联发科MT8365(Genio 350)核心板规格参数
  • 第二章 Redis介绍及安装
  • 前端常见标签
  • Android systemui 编译
  • 参考数据集INRIA Holidays dataset
  • GO EASY 框架 之 NET 05
  • Banana Pi BPI-R4开源路由器开发板快速上手用户手册,采用联发科MT7988芯片设计
  • 2024 高级前端面试题之 HTTP模块 「精选篇」
  • vscode实时预览markdown效果
  • 类银河恶魔城学习记录1-5 CollisionCheck源代码 P32
  • 基于WordPress开发微信小程序2:决定开发一个wordpress主题
  • P8706 [蓝桥杯 2020 省 AB1] 解码--2024蓝桥杯冲刺省一
  • Javascript第八个知识点:函数
  • 华为数通方向HCIP-DataCom H12-831题库(填空题)
  • MySQL运维实战(5.3) MySQL数据乱码的一些情况
  • Akka系列(七):Actor持久化之Akka persistence
  • Android Volley源码解析
  • Javascript设计模式学习之Observer(观察者)模式
  • Java程序员幽默爆笑锦集
  • Laravel5.4 Queues队列学习
  • leetcode388. Longest Absolute File Path
  • markdown编辑器简评
  • Protobuf3语言指南
  • tensorflow学习笔记3——MNIST应用篇
  • 服务器从安装到部署全过程(二)
  • 关于 Linux 进程的 UID、EUID、GID 和 EGID
  • 基于Javascript, Springboot的管理系统报表查询页面代码设计
  • 基于遗传算法的优化问题求解
  • 今年的LC3大会没了?
  • 前端性能优化--懒加载和预加载
  • 如何实现 font-size 的响应式
  • 一天一个设计模式之JS实现——适配器模式
  • 移动端解决方案学习记录
  • [地铁译]使用SSD缓存应用数据——Moneta项目: 低成本优化的下一代EVCache ...
  • !!【OpenCV学习】计算两幅图像的重叠区域
  • # Java NIO(一)FileChannel
  • # MySQL server 层和存储引擎层是怎么交互数据的?
  • #define、const、typedef的差别
  • (23)Linux的软硬连接
  • (27)4.8 习题课
  • (C语言)逆序输出字符串
  • (vue)页面文件上传获取:action地址
  • *++p:p先自+,然后*p,最终为3 ++*p:先*p,即arr[0]=1,然后再++,最终为2 *p++:值为arr[0],即1,该语句执行完毕后,p指向arr[1]
  • .[hudsonL@cock.li].mkp勒索病毒数据怎么处理|数据解密恢复
  • .NET 8 编写 LiteDB vs SQLite 数据库 CRUD 接口性能测试(准备篇)
  • .net core webapi Startup 注入ConfigurePrimaryHttpMessageHandler
  • .Net Core缓存组件(MemoryCache)源码解析
  • .NET/C# 使用反射注册事件
  • ::前边啥也没有
  • @ 代码随想录算法训练营第8周(C语言)|Day57(动态规划)
  • @Mapper作用
  • @RequestMapping处理请求异常
  • @Transactional注解下,循环取序列的值,但得到的值都相同的问题
  • [ 隧道技术 ] cpolar 工具详解之将内网端口映射到公网
  • [【JSON2WEB】 13 基于REST2SQL 和 Amis 的 SQL 查询分析器