我们继续说一些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"的使用方法。如果大家觉得有帮助,可以点赞收藏,谢谢大家!

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

被折叠的 条评论
为什么被折叠?



