IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++初阶之函数重载 -> 正文阅读

[C++知识库]C++初阶之函数重载

目录

1.函数重载

1.1 概念

1.2 C++支持函数重载的原因

2.extern “C”

2.1 C++调用C语言写的静态库

2.2 C调用C++写的静态库

? ? ? ? 在自然语言中,一个词可以有多种意思,人们可以通过联系上下文来判断这个词的真正意思,放在编程语言中,就可以称这个词被重载了

1.函数重载

1.1 概念

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

? ? ? ? 举个栗子:

//参数类型不同

int ADD(int a, int b)
{
    return a+b;
}

double ADD(double a, double b)
{
    return a+b;
}

//参数顺序不同

void func(int a, double b)
{
    cout << "int func(int a, double b)" << endl;
}

void func(double a, int  b)
{
    cout << "int func(double a, int b)" << endl;
}

//参数个数不同

void test()
{
    cout << "void test()" << endl;
}

void test(int a)
{
    cout << "void test(int a)" << endl;    
}

1.2 C++支持函数重载的原因

? ? ? ? C语言是不支持函数重载的,这是为啥呢?

? ? ? ? 在程序运行过程中,要经历预处理,编译,汇编,链接四个步骤,源文件通过前三步生成目标文件,但是编译时独立的,在编译结束生成的目标文件中,在调用函数的地方就会换成经过修饰的函数名,相应的也就有符号表——C语言和C++的名字修饰规则不同,这也是为什么C++支持函数重载而C语言不支持的关键所在。在链接的过程中,编译器自己会在符号表中找相对应的函数名,进而找到地址进行链接,完成程序的运行,此时,C语言的名字修饰规则会使重名的函数无法区分,编译器分别不了,就会出现连接错误

????????以下是在Linux系统中编写的C语言程序,以及生成的函数符号

?我们可以清楚地看到,在Linux环境下,C语言程序的函数名字修饰规则就是直接取函数名,那么必然函数重名会使得编译器分别不了,所以C语言不支持函数重载

????????以下是在Linux系统中编写的C++程序,以及生成的函数符号

?对比着C语言程序生成地函数符号,我们可以清楚地看到C++的名字修饰是将参数的类型也放了进去,这样使得即使函数重名,但是参数不同时,生成的符号名也不同,这样编译器在寻找的时候就不会出现C语言中分不清的情况了

????????上面展示的是在Linux环境下C语言与C++的名字修饰规则,Windows环境下相较要麻烦许多,想要了解的朋友可以自行百度,这里我就不再赘述了

注意:

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

2.extern “C”

????????我们都知道C++是兼容C语言的,那么C语言程序能否调用C++写的库呢?C++程序又能否调用C语言写的程序呢?回答是肯定的,但是需要借助extern “C”来完成

2.1 C++调用C语言写的静态库

? ? ? ? 首先生成C语言写的静态库,我们将C语言实现的Stack程序生成静态库,如果我们直接编译程序,会出现下图所示错误(因为我们没写主函数)

?????????此时编译器默认生成.exe文件,但我们需要的是.lib的文件,按照下图的操作进行处理,可生成静态库

????????完成修改后重新生成解决方案,就可以得到C语言写的静态库了,如下图

?????????此时我们重开一个项目,用C++程序来调用这个库,发现编译报错,我们知道如果要用相应的函数需要包含相应的头文件,但是编译后还是会出现错误,如下两图

?????????编译器默认到当前文件路径去找相应的文件,而我们的静态库文件不在此处,我们可以使用相对路径或者绝对路径去找目标头文件,我在这就使用绝对路径了

?????????此时我们重新编译发现还是不对,我们还需要进行处理,如下两图

?????????完成上面的步骤进行重新生成解决方案,发现编译链接都没问题了,但是找不着函数名,这是因为我们使用的是C语言所写的库,使用的名字修饰规则是C语言的,C++不认识,此时,extern就上场了~

?????????上面的语句是向编译器说明,这个库是用的C语言的名字修饰,因为C++兼容C语言,那么C++肯定知道C语言的名字修饰规则,就在执行的时候按照C语言的规则来了,这样程序就能跑起来了~

2.2 C调用C++写的静态库

????????前面的步骤和C++调用C语言写的静态库一样,先生成C++的静态库,再重开一个程序,用C的程序去调用C++写的静态库

????????但是,extern “C”是C++的语法,C语言编译器是不认识的,所以我们不能在调用C++静态库的C语言程序中做文章,而是应该在C++所写的静态库中做文章,我们的目的是让函数在编译的时候按照C语言的名字修饰规则生成函数的符号表,我们想当然的就会在函数声明出直接加extern,如下图

?????????当我们重新生成静态库,再去调用时,会发现还是不行,这是为什么呢?

????????因为我们引用的头文件会在被引用处直接展开,那么也就是说上图显示的代码会直接展开在C语言的程序中,问题又回来了,C语言是不认识extern的,那该怎么解决这个问题呢?

????????使用条件编译可以很好的解决这个问题,如下图

?????????然后再重新生成解决方案,就可以实现C语言程序调用C++写的静态库了~

以上就是本篇博客的全部内容了~

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-08-06 10:25:04  更:2022-08-06 10:26:22 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/9 12:15:30-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码