函数重载及简述其实现原理

简介: 本文将讲述,函数重载及简述其实现原理。

前言

本文将讲述,函数重载及简述其实现原理。


🕺作者: 迷茫的启明星


😘欢迎关注:👍点赞🙌收藏✍️留言


🏇家人们,码字不易,你的👍点赞🙌收藏❤️关注对我真的很重要,有问题可在评论区提出,感谢阅读!!!


持续更新中~


函数重载

在汉语中,一个词可以有多重含义,在之前朋友圈经常刷到的一句话:


“以前我喜欢一个人,现在我喜欢一个人”


怎么理解呢?


可以是以前喜欢一个人自由自在的,现在喜欢上了另一个人


也可以是以前喜欢过一个人,但是被情所伤,现在喜欢自己一个人生活


在C++中也有相同的应用:函数重载


函数重载的概念

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


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 f(double d)
{
}
void f(double d)
{
}

缺省值不同呢?不能,因为调用的时候不能区分


void f(int a)
{
   cout << "f()" << endl;
}
void f(int a = 0)
{
   cout << "f(int a)" << endl;
}


一个无参、一个有参但是是全缺省:构成重载但是使用时会出问题,调用存在歧义


void f()
{
   cout << "f()" << endl;
}
void f(int a = 0)
{
   cout << "f(int a)" << endl;
}
int main()
{
   f(); // 调用存在歧义
   return 0;
}


image.png


函数重载原理


我们都知道C语言是不能重载的,但是为什么不能呢?


我们先来验证一下C语言是否真的不能重载


显然 是不能的

image.png



那么是为什么呢?


这与C语言编译器有关


这就不得不提程序是怎么运行起来的


show.c show.h test.c


预处理–>头文件展开、宏替换、条件编译、去掉注释


show.i test.i


编译–>检查语法,生成汇编代码


show.s test.s


汇编–>汇编代码转换为二进制代码


show.o test.o


链接–>合并段表


a.out


再简单介绍一下链接的工作:


如果当前文件有函数的定义,那么再编译时就填上地址了


如果当前文件只有函数的声明,那么定义就在其他的源文件中,


编译时没有地址,只能再编译的时候去其它.o符号表中1根据函数修饰名字去找


在C语言中不能实现重载的原因是,汇编和链接时对函数的修饰名规则所致,


它在调用时仅仅使用函数名来区分,如果在show.c文件中去写一个重载的函数,


汇编时在show.o 符号表中存在歧义和冲突,在链接的时候也存在歧义和冲突,


因为它们都是直接使用函数名去标识和查找的,而函数名相同。


而在C++中,它的目标文件符号表不是直接使用函数名来标识和查找函数的,


它有与C不同的函数名修饰规则,但是这个规则不同的编译器下面不同,


有了函数名修饰规则,只要参数不同,


show.o 符号表里面重载的函数就不存在歧义和冲突了,


在链接的时候,test.o的main函数里面去调用两个重载的函数,查找地址时也是明确的。


linux下的g++的修饰函数名规则(也就是对C++的)


_Z + 函数名长度 + 函数名 + 参数首字母


示例:


void f(){}
void f(int a){}
void func(int a,int*p){}




image.png


linux下的C语言的修饰函数名规则


void f(){}
void func(int a,int*p){}




image.png


以上可以验证前面所说的函数名修饰规则。


总结

本文讲述了,函数重载及简述其实现原理,下一篇将讲述引用&


respect !


下篇见!

相关文章
|
8天前
|
编译器
什么是函数重载?作用是什么?如何使用?
什么是函数重载?作用是什么?如何使用?
17 1
|
6月前
|
存储 Cloud Native 编译器
C++ 多态实现原理
C++ 多态实现原理
|
2天前
|
存储 编译器 C语言
从C语言到C++④(第二章_类和对象_上篇)->类->封装->this指针(中)
从C语言到C++④(第二章_类和对象_上篇)->类->封装->this指针
5 0
|
8天前
|
C++
关于C++多态 的基本知识 与 底层原理
关于C++多态 的基本知识 与 底层原理
|
8天前
|
存储 编译器 程序员
【C/C++ 基础知识 】深入C++:特殊成员函数的底层原理与规则
【C/C++ 基础知识 】深入C++:特殊成员函数的底层原理与规则
61 0
|
8天前
|
SQL 关系型数据库 MySQL
搞懂connectTimeout和socketTimeout的区别
搞懂connectTimeout和socketTimeout的区别
77 0
|
10月前
|
C++
【C++多态】 --- 多态实现原理简析
【C++多态】 --- 多态实现原理简析
74 0
|
11月前
理解多态的实现原理
理解多态的实现原理
45 0
setlocale函数是干什么的?底层原理是什么?
setlocale函数是干什么的?底层原理是什么?
389 0
简述for in 和 for of 的区别
1、推荐在循环对象属性的时候使用 for...in,在遍历数组的时候的时候使用 for...of 2、for...in 循环出的是 key,for...of 循环出的是 value
124 0
简述for in 和 for of 的区别

热门文章

最新文章