什么是函数重载
一组函数,其中函数名相同,参数列表的个数或者类型不同,那么这一组函数就称作函数重载。
#include<iostream>
using namespace std;
bool compare(int a, int b)
{
cout << "compare_int_int" << endl;
return a > b;
}
bool compare(double a, double b)
{
cout << "compare_double_double" << endl;
return a > b;
}
bool compare(const char * a, const char * b)
{
cout << "compare_char *_char*" << endl;
return strcmp(a, b) > 0;
}
int main()
{
compare(10, 20);//匹配第一个函数
compare(10.0, 20.0);//匹配第二个函数
compare("aaa","bbb" );//匹配第三个函数
return 0;
}
C++为什么支持函数重载,C语言不支持
主要原因: 编译器编译代码产生的规则不同
- C++代码在产生符号的时候是由函数名加参数列表组成
- C代码产生函数符号的时候,是由函数名来决定,会出现链接错误,找到多个符号的定义。
函数重载需要注意的
- 一组函数要称得上重载,一定先是处在同一个作用域中
#include<iostream>
using namespace std;
bool compare(int a, int b)
{
cout << "compare_int_int" << endl;
return a > b;
}
bool compare(double a, double b)
{
cout << "compare_double_double" << endl;
return a > b;
}
bool compare(const char * a, const char * b)
{
cout << "compare_char *_char*" << endl;
return strcmp(a, b) > 0;
}
int main()
{
bool compare(int a, int b);//函数的声明
compare(10, 20);//匹配main中的compare(int a, int b)
compare(10.0, 20.0);//匹配main中的compare(int a, int b)
compare("aaa","bbb" );//匹配main中的compare(int a, int b)
return 0;
}
无法正确匹配的原因:
与作用域有关,编译器会在调用函数的时候优先去本地局部作用域中的函数进行匹配。
因此函数重载的一个重要条件就是处在同一个作用域,不在同一个作用域中的函数谈不上重载。
- 给参数加const或volatile的时候,如何影响形参类型
#include<iostream>
#include<typeinfo>
using namespace std;
//不是重载
void func(int a) {} //对于编译器来说,该形参类型是int
void func(const int a) {} //对于编译器来说,该形参类型也是int
int main()
{
int a = 10;
const int b = 10;
cout << typeid(a).name() << endl; //int
cout << typeid(b).name() << endl; //int
return 0;
}
- 一组函数,函数名相同,参数列表也相同,仅仅是返回值不同,不叫函数重载(因为生成符号的时候与返回值无关)
- 函数重载属于静态多态(编译时期的多态)
函数调用选择调用版本是在编译时期就确定好的。
C++和C语言代码之间如何互相调用
C调用C++
test1.c
#include<stdio.h>
int sum(int, int);// _sum "UND"
int main()
{
int ret = sum(10, 20);
printf("ret=%d\n", ret);
}
test.cpp
#include<iostream>
#include<typeinfo>
using namespace std;
int sum(int a, int b) //sum_int_int .text
{
return a + b;
}
test.cpp
#include<iostream>
#include<typeinfo>
using namespace std;
extern "C"
{
int sum(int a, int b)
{
return a + b;
}
}
生成符号的方式不同,导致找不到该符号定义的地方。无法直接调用。
解决办法:把C++中源码括在extern "C"里
C++调用C代码
test1.c
int sum(int a, int b) //sum .text
{
return a + b;
}
test.cpp
#include<iostream>
#include<typeinfo>
using namespace std;
int sum(int a, int b); //sum_int_int “UND”
int main()
{
int ret = sum(10, 20);
cout << "ret:" << ret << endl;
}
生成符号的方式不同,导致找不到该符号定义的地方。无法直接调用。
解决办法:把C函数的声明括在extern "C"里
告诉编译器,该函数是在C语言规则下生成的,在生成该函数的符号的时候不要用C++的方式生成,要按照C语言的规则来生成。符号解析才会成功。
test.cpp
#include<iostream>
#include<typeinfo>
using namespace std;
extern "C"
{
int sum(int a, int b);
}
int main()
{
int ret = sum(10, 20);
cout << "ret:" << ret << endl;
}
拓展知识
只要是C++编译器,都内置了__cplusplus这个宏名
如果是C编译器,没有该宏名,就进不来,也就不会处理。生成的函数,也是C符号。
#ifdef __cplusplus
extern "C"
{
#endif
int sum(int a, int b)
{
return a + b;
}
#ifdef __cplusplus
}
#endif
按照以上定义的宏,不管是用C编译器生成还是C++编译器生成该函数,都是可以给其他C项目来调用,代码的编译是通用的,比较灵活。
以下的只能在C++编译器中,因为C编译器不认识
extern "C"
{
int sum(int a, int b)
{
return a + b;
}
}