目录
函数重载
定义
举例
函数
注意
原因
c:
c++:
总结
创建一个C的静态库
将一个栈封装成一个静态库
c++调用c++库和c库
头文件包含
配置静态库
原因
c++调用c++库
c++调用C库
c调用c库和c++库
创建cpp的栈的静态库
更改库的配置
c调用c库
c调用c++库
为什么还是链接不上呢?
怎么才能链接成功呢?
原因
第一种
第二种
总结
是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 顺序)必须不同,常用来处理实现功能类似数据类型不同的问题。
同名的函数,参数类型不同,那么构成重载函数,在c++中可以顺利运行
#include
using namespace std;
int Add(int left, int right)
{
return left + right;
}
double Add(double left, double right)
{
return left + right;
}
int main()
{
cout << Add(1,2) << endl;
cout << Add(1.3, 2.4) << endl;
return 0;
}
在c中运行失败:
double compare(int,int)
重载函数有:
int compare(double,double)
double compare(double,double)
double compare(double,int)
double compare(int,double)
//……………………等等
只与形参的类型,顺序,个数有关,与返回的类型无关,只要参数的类型、顺序、大小和原函数有所区别,那么返回类型可以任意,都构成重载函数。
若函数的参数类型,大小,顺序与原函数相同,但是返回类型不同,是不构成重载函数的
double compare(int,int)
int compare(int,int)
//不构成
在vs环境下不好区分,在Linux环境下编译区别:
c的编译器中,对函数的命名规则:
直接用我们给定的函数名进行编译
重载函数的函数名相同,编译时会发生访问冲突
c++的编译器中,对函数的命名规则:
_Z + 函数名长度 + 函数名 +参数类型的首字母
即使函数名相同,命名规则保证了编译时每个函数名的唯一性
访问不会发生冲突
在c中,链接时,c中的函数名是直接以我们给的函数名确定的。
而在c++中,函数名的命名规则是_Z + 函数名长度 + 函数名 +参数类型的首字母
即使函数名相同的两个函数,只要符合重载条件,在c++中调用不会发生冲突。
因为函数名命名规则不同,c不支持函数重载。
无论在那个环境下,c++保证了重载函数函数名的唯一性。
将已经写好的栈的声明和定义在VS中打开,此时没有主函数,运行时编译器将项目当成一个可执行文件,进行运行,会报错,如下图:
接下来我们开始对此进行封装:
在此项目对应的文件下,就能找到封装的静态库:
创建一个.cpp的项目,在主函数中用栈中的函数创建栈,初始化栈,销毁栈,如下图:
项目识别不了我们的操作。
这里我们包含头文件必须要包含到栈的头文件才行,不在一个项目中,我们使用相对路径解决这个问题:
接下来我们包含头文件,要用到相对文件路径,直接在文件目录中找栈的头文件,从上图路径开始,向上一层,没有找到:
再向上一层,找到关于栈的静态库文件:
进入此路径下,找到此文件:
进入此文件下,找到栈的头文件:
包含头文件过程如下:
#include "../../Stack_C.lib/Stack_C.lib/Stack.h"
. . 是跳到上级目录,如上图,我们向上跳了两次,找到了静态库的文件,接下来就是正常的在路径下找头文件。包含头文件后,就可以识别对栈相关的操作:
直接调用c库会失败,这里还需要进行配置
如下图操作:
点击编辑,进行如下图操作:
效果如下:
之后,在静态库的文件下,在Debug下,找到静态库,将其文件名包括后缀都复制下来
再次运行:
依旧是无法链接
c库中函数的命名就是以我们给的函数名,而c++中的命名规则是_Z + 函数名长度 + 函数名 + 参数类型的首字母,进行完预编译,编译和汇编后,进行链接时,c++在c库中找不到对应的函数名,因此链接失败。
若我们将Stack.c改为Stack.cpp,运行一次,这样刚刚的c静态库,就会更新成c++的静态库
之后再运行test.cpp ,此时就是c++调用c++的静态库了
我们将Stack.cpp,改回来Stack.c,再次运行生成c的静态库
那么我想要用c++来调用c的静态库怎么办?
用到 entern"C",这是C++中的语法。
告诉编译器,用的是C库,用C的方式去链接,这样就可以链接成功。
extern "C"
{
#include "../../Stack_C.lib/Stack_C.lib/Stack.h"
}
生成解决方案,在相对路径中可以找到该静态库
此时,运行test.c,就是c调用c库
将Stack.c改回Stack.cpp,生成解决方案,静态库变回c++的静态库,运行test.c,就是c调用c++的静态库,如下:
原因和c++直接调用c库链接不上的原因相同,c和c++库中,对函数的命名规则不同,c在c++的静态库中找不到对应的函数名,因此链接失败。
有同学可能会说,在test.c中用 extern ,试试,这个语法是c++中的,不能在c中调用,想法不成立。
既然 entern 是c++的语法,那么我们把entern "C",就用在 Stack.cpp 中,再生成解决方案,更新c++的静态库。
告诉编译器在c++的静态库中用C的方式去修饰这些函数。
如下:
再次运行test.c :
头文件展开时,会将entern "C" ,放入test.c中,c识别不了这个语法,因此运行不通过。
但是思想是正确的,怎么样才能让 entern "C" 在 .cpp中出现,在.c中消失呢?
这里可以用条件编译来解决:
更推荐第一种,直接用entern "C" ,包含所有函数,当函数很多时,更加高效!
c调用c++库,c++调用c库,都是在c++中做出调整,按c的规则对函数进行修饰!
链接失败的原因就是c++和c对函数的命名规则不同,这也是c++支持函数重载的原因!