C++入门——重载

我们继续说一些C++入门的知识,这一篇我就详细说一下关于函数重载的内容。
C++入门——重载_第1张图片

文章目录

  • 1. 函数重载
    • 1.1 什么是函数重载
    • 1.2 C++支持函数重载的原理--名字修饰
  • 2. extern “C”
    • 2.1 C++工程中使用C语言静态库
    • 2.2 C工程中使用C++静态库

1. 函数重载

1.1 什么是函数重载

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

举个例子:
C++入门——重载_第2张图片
这里的顺序不同是什么意思呢?
C++入门——重载_第3张图片
下面有一个问题:这两个函数属于函数重载吗?

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++入门——重载_第4张图片
C++入门——重载_第5张图片
C++入门——重载_第6张图片
我们知道:在C/C++中,一个程序要运行起来,需要经历以下几个阶段:预处理、编译、汇编、链接
C++入门——重载_第7张图片
在这里,符号表里存着有函数名和函数的地址
C++入门——重载_第8张图片
当我们去调用某些函数时,我们就会去找这些函数名和对应的地址。

那么,准备知识说完,我们先将f.cpp和test.cpp编译链接成可执行程序:
C++入门——重载_第9张图片
然后我们来查看一下:
C++入门——重载_第10张图片
从上面可以看出:g++的函数修饰后变成【_Z+函数长度+函数名+类型首字母】。因为名字不同,链接时就可以按照名字来找对应的地址,重载就完成了。
然后我们在看一下C语言的编译情况:
C++入门——重载_第11张图片
在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++入门——重载_第12张图片
然后我们把C语言写的一个栈添加进来:
C++入门——重载_第13张图片
然后我们右键整个Stack_C属性。然后点配置类型,选静态库:
C++入门——重载_第14张图片
此时我们编译一下:
C++入门——重载_第15张图片
可以看到在debug下生成了一个静态库。

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

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

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

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

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

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

你可能感兴趣的:(C++,c++)