一、C++中的函数重载:
1、函数重载的概念:
代码示例演示:
#include <stdio.h>
#include <string.h>
int func(int x)
{
return x;
}
int func(int a, int b)
{
return(a+b);
}
int func(const char* s)
{
return strlen(s);
}
int main()
{
return 0;
}
上面在c++编译器里面编译时没有问题的,如果放在c语言编译器里面编译是会报错的:
root@txp-virtual-machine:/home/txp# gcc test5.c
test5.c:8:5: error: conflicting types for ‘func’
int func(int a, int b)
^
test5.c:3:5: note: previous definition of ‘func’ was here
int func(int x)
^
test5.c:13:5: error: conflicting types for ‘func’
int func(const char* s)
^
test5.c:3:5: note: previous definition of ‘func’ was here
int func(int x)
所以说c语言里面不支持函数重载。
2、函数重载至少要满足下面的一个条件:
比如下面两个函数可以构造重载函数吗?
int func (int a,const char* s)
{
return a;
}
int func(const char*s,int a)
{
return strlen(s)
}
答案肯定是可以构造重载函数的,读者可以自己试试(这个比较好理解)。
3、当函数默认参数遇上函数重载会发生什么?
例如下面的两个函数:
int func(int a, int b, int c =0)
{
return a*b*c;
}
int func(int a, int b)
{
return a+b;
}
到底会发生啥,我们还是看下面这个实验:
#include <stdio.h>
int func(int a, int b, int c = 0)
{
return a * b * c;
}
int func(int a, int b)
{
return a + b;
}
int main(int argc, char *argv[])
{
int c = func(1, 2);
return 0;
}
运行结果:
root@txp-virtual-machine:/home/txp# g++ test5.cpp
test5.cpp: In function ‘int main(int, char**)’:
test5.cpp:16:22: error: call of overloaded ‘func(int, int)’ is ambiguous
int c = func(1, 2);
^
test5.cpp:16:22: note: candidates are:
test5.cpp:3:5: note: int func(int, int, int)
int func(int a, int b, int c = 0)
^
test5.cpp:8:5: note: int func(int, int)
int func(int a, int b)
从上面报错的结果里面有一个单词ambiguous(意思是梦棱两可的),也就是说默认参数这种使用时不允许的。
4、C++编译器调用重载函数的准则:
通过默认参数能够匹配实参
通过默认类型转换匹配实参
最终寻找到的候选函数不唯一,则出现二义性,编译失败
无法匹配所有候选者,函数未定义编译失败
5、函数重载的注意事项:
代码测试:
#include <stdio.h>
int add(int a, int b) // int(int, int)
{
return a + b;
}
int add(int a, int b, int c) // int(int, int, int)
{
return a + b + c;
}
int main()
{
printf("%p\n", (int(*)(int, int))add);
printf("%p\n", (int(*)(int, int, int))add);
return 0;
}
运行结果:
root@txp-virtual-machine:/home/txp# ./a.out
0x40052d
0x400541
从输出结果我们可以看出这两个函数的入口地址不一样,这表明这两个函数是不同的函数。
6、小结:
二、重载函数进阶学习
1、重载与指针:
下面的函数指针将保存哪个函数的地址?
int func(int x)
{
return x;
}
int func(int a, int b)
{
return a+b;
}
int func(const char* s)
{
return strlen(s);
}
typedef int (*PFUNC) (int a);
int c =0;
PFUNC p = func;
c = p(2)//到底选择哪个func函数
函数重载遇上函数指针:
代码试验:
#include <stdio.h>
#include <string.h>
int func(int x)
{
return x;
}
int func(int a, int b)
{
return a+b;
}
int func(const char* s)
{
return strlen(s);
}
typedef int(*PFUNC)(int a);
int main(int argc,char *argv[])
{
int c =0;
PFUNC p =func;
c = p(2);
printf("c=%d\n",c);
return 0;
}
输出结果:
root@txp-virtual-machine:/home/txp# ./a.out
c=2
从输出结果来看,很明显调用了第一个func函数。
2、注意:
无法直接通过函数名得到重载函数的入口地址,这里还是通过上面的例子演示一下:
#include <stdio.h>
int add(int a, int b) // int(int, int)
{
return a + b;
}
int add(int a, int b, int c) // int(int, int, int)
{
return a + b + c;
}
int main()
{
printf("%p\n", add);
printf("%p\n", add);
return 0;
}
输出结果:
root@txp-virtual-machine:/home/txp# g++ test5.cpp
test5.cpp: In function ‘int main()’:
test5.cpp:15:23: error: overloaded function with no contextual type information
printf("%p\n", add);
^
test5.cpp:16:23: error: overloaded function with no contextual type information
printf("%p\n", add);
三、C++和C相互调用:
extern关键字能够强制让C++编译器进行c方式的编译:
extern "c"
{
}
1、下面进行一个c++中调用c函数,这里我在当前创建三个文件:add.c 、add.h 、main.cpp。内容分别如下:
add.c内容:
#include "add.h"
int add(int a, int b)
{
return a + b;
}
add.h内容:
int add(int a, int b);
然后我用gcc编译编译生成add.o文件:
root@txp-virtual-machine:/home/txp/add# vim add.c
root@txp-virtual-machine:/home/txp/add# vim add.h
root@txp-virtual-machine:/home/txp/add# gcc -c add.c -o add.o
root@txp-virtual-machine:/home/txp/add# ls
add.c add.h add.o
然后main.cpp里面调用add.c
#include <stdio.h>
int main()
{
int c = add(1, 2);
printf("c = %d\n", c);
return 0;
}
输出结果:
root@txp-virtual-machine:/home/txp/add# g++ main.cpp add.o
/tmp/ccqz3abQ.o: In function `main':
main.cpp:(.text+0x13): undefined reference to `add(int, int)'
collect2: error: ld returned 1 exit status
结果显示找不到这个函数,为了能够在c++里面调用c语言里面的函数,我们就要使用刚才上面讲的第四点了;这里我们先用nm命令来查看一下add.o文件里面是否生成符号表(有生成):
root@txp-virtual-machine:/home/txp/add# nm add.o
0000000000000000 T add
解决方法,main.cpp改成:
#include <stdio.h>
extern "c"
{
#include "add.h"
}
int main()
{
int c = add(1, 2);
printf("c = %d\n", c);
return 0;
}
输出结果:
root@txp-virtual-machine:/home/txp/add# ./a.out
c = 3
2、c中如何调用c++函数:
这里我把main.cpp的内容改成:
extern "C"
{
int add(int a, int b);
}
int add(int a, int b)
{
return a+b;
}
编译输出:
root@txp-virtual-machine:/home/txp/add# g++ -c main.cpp -o test.o
root@txp-virtual-machine:/home/txp/add# nm -s test.o
0000000000000000 T add
add.c文件内容改成:
#include <stdio.h>
int main()
{
int c =0;
c = add(2,3);
printf("c=%d\n",c);
return 0;
}
输出结果:
root@txp-virtual-machine:/home/txp/add# gcc add.c test.o
root@txp-virtual-machine:/home/txp/add# ./a.out
c=5
3、如何保证一段c代码只会以c的方式被编译?
解决方法如下:
#ifdef __cplusplus
extern "C"
{
#endif
#ifdef __cplusplus
}
#endif
这里把main.cpp改成:
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
#include "add.h"
#ifdef __cplusplus
}
#endif
int main()
{
int c = add(1, 2);
printf("c = %d\n", c);
return 0;
}
输出结果:
root@txp-virtual-machine:/home/txp/add# g++ main.cpp add.o
root@txp-virtual-machine:/home/txp/add# ./a.out
c = 3
4、注意事项
int add(int a, int b)
{
return a+b;
}
int add(int a, int b , int c)
{
return a+b+c;
}
编译输出:
root@txp-virtual-machine:/home/txp/add# g++ -c main.cpp -o test.oo
root@txp-virtual-machine:/home/txp/add# nm test.oo
0000000000000000 T _Z3addii
0000000000000014 T _Z3addiii
说明ii表示两个参数,iii表示三个参数
extern "C"
{
int add(int a, int b)
{
return a+b;
}
int add(int a, int b , int c)
{
return a+b+c;
}
}
输出结果:
root@txp-virtual-machine:/home/txp/add# g++ -c main.cpp -o test.oo
main.cpp: In function ‘int add(int, int, int)’:
main.cpp:8:29: error: declaration of C function ‘int add(int, int, int)’ conflicts with
int add(int a, int b , int c)
^
main.cpp:3:5: error: previous declaration ‘int add(int, int)’ here
int add(int a, int b)
目标名起冲突所以报错。
5、小结:
四、总结:
好了,今天的分享就到这里,如果文章中有错误或者不理解的地方,可以交流互动,一起进步。我是txp,下期见!
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有