C++入门——重载

"本文介绍了C++中的函数重载原理,解释了如何通过参数列表来区别同名函数,并探讨了C++支持函数重载的原因。同时,讲解了在C++与C混合编程时如何使用`extern"C"`来解决名称修饰问题,包括在C++工程中调用C语言静态库和C工程中使用C++静态库的配置方法。"
摘要由CSDN通过智能技术生成

我们继续说一些C++入门的知识,这一篇我就详细说一下关于函数重载的内容。
在这里插入图片描述

1. 函数重载

1.1 什么是函数重载

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

举个例子:
在这里插入图片描述
这里的顺序不同是什么意思呢?
在这里插入图片描述
下面有一个问题:这两个函数属于函数重载吗?

short Add(short left, short right) 
{
 return left+right; 
}


int Add(short left, short right) 
{
 return left+right; 
}

这两个不是函数重载,函数重载不能根据返回值来判断。

1.2 C++支持函数重载的原理–名字修饰

为什么C++支持函数重载,而C语言不支持函数重载呢?
这个问题,我们要在Linux下演示:
首先,我们创建三个文件:f.h,f.cpp,test.cpp
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我们知道:在C/C++中,一个程序要运行起来,需要经历以下几个阶段:预处理、编译、汇编、链接
在这里插入图片描述
在这里,符号表里存着有函数名和函数的地址
在这里插入图片描述
当我们去调用某些函数时,我们就会去找这些函数名和对应的地址。

那么,准备知识说完,我们先将f.cpp和test.cpp编译链接成可执行程序:
在这里插入图片描述
然后我们来查看一下:
在这里插入图片描述
从上面可以看出:g++的函数修饰后变成【_Z+函数长度+函数名+类型首字母】。因为名字不同,链接时就可以按照名字来找对应的地址,重载就完成了。
然后我们在看一下C语言的编译情况:
在这里插入图片描述
在linux下,采用gcc编译完成后,函数名字的修饰没有发生改变。

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

2. extern “C”

由于C和C++编译器对函数名字修饰规则的不同,在有些场景下可能就会出问题,比如:
1.C++中调用C语言实现的静态库或者动态库,反之亦然
2.多人协同开发时,有些人擅长用C语言,有些人擅长用C++
在这种混合模式下开发,由于C和C++编译器对函数名字修饰规则不同,可能就会导致链接失败,在该种场景下,就需要使用extern “C”。在函数前加extern “C”,意思是告诉编译器,将该函数按照C语言规则来编译

2.1 C++工程中使用C语言静态库

下面演示一个在C++工程中使用C语言静态库的例子
首先,我们正常的创建一个空项目:
在这里插入图片描述
然后我们把C语言写的一个栈添加进来:
在这里插入图片描述
然后我们右键整个Stack_C属性。然后点配置类型,选静态库:
在这里插入图片描述
此时我们编译一下:
在这里插入图片描述
可以看到在debug下生成了一个静态库。

现在,我们想在另外一个项目中去使用这个静态库。首先,要包含头文件。之前的头文件是直接在项目下的,现在不在了,我们需要根据路径来找头文件(这里用的是相对路径)。
在这里插入图片描述
现在,我们想使用这个栈:
在这里插入图片描述
这是一个括号匹配问题。
在这里插入图片描述
但是发现链接失败了,因为我们只有这些函数的声明,但定义不在。我们需要在这个C++项目进行一些配置:
在这里插入图片描述
点链接器里的常规,然后添加库目录:
在这里插入图片描述
然后我们需要将静态库下的debug目录添加进去。
在这里插入图片描述
然后我们在这个附加依赖项里,添加静态库下debug下的.lib文件。
在这里插入图片描述
注意:我们添加时需要以分号隔开。

现在环境配置都弄好了,如果静态库是.c
在这里插入图片描述
在这里插入图片描述
还是不行,CPP项目不能直接去调用C项目,因为它们函数的命名规则不同。这时,我们就可以使用extern “C”
在这里插入图片描述
这个的意思是: 告诉编译器,extern "C"声明的函数,是C库,要用c的方式去链接调用
这样,我们就可以在C++里去调用C的了。

2.2 C工程中使用C++静态库

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
但是此时,C工程中调用C++静态库,extern "C"就不能使用了,因为extern "C"这个语法C语言不支持。
在这里插入图片描述
我们还是需要在C++静态库里做一些工作:
在这里插入图片描述
但是此时还是不行。因为在头文件展开时,还是在C里,C不支持extern “C”。

此时我们需要使用条件编译:
在这里插入图片描述
或者这样写:
在这里插入图片描述
__cplusplus:是C++编译器中定义的宏,即用该宏来检测是C工程还是C++工程
如果是C++工程,编译器已经定义_cplusplus宏,编译时该宏是可以被识别的,被声明的函数就被extern "C"修饰了,此时C++编译就知道,静态库中的函数是按照C的方式编译的,这样在链接时就会按照C的方式找函数名字如果是C工程,编译器未定义_cplusplus宏,编译时该宏无法被是被,则条件编译就无效,函数就不会被extern "C"修饰
在这里插入图片描述

好了,到这里我们重载的原理和extern "C"的使用都说明了。大家一定要掌握extern "C"的使用方法。如果大家觉得有帮助,可以点赞收藏,谢谢大家!
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学代码的咸鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值