4 函数的升级-下

重载(overload)

同一个标识符在不同的上下文有不同的意义
如汉语中“洗”和不同的字搭配后,有不同的含义,play 和不同的单词搭配后有不同的含义。
函数重载:用同一个函数名定义不同的函数,通过不同的参数搭配来判断不同的函数
编译器通过不同的参数来区分不同的功能。

#include 
#include 

int func(int x) { //一个int 型参数
    return x;
};
int func(int a, int b) { //两个int型参数
    return a + b;
}
int func(char* s) { //一个char* 参数
    return strlen(s);
}

int main(int argc, char *argv[])
{
	int a, b, c;
	a = func(1);
	b = func(2, 3);
	c = func("abcdef");
	printf("a = %d, b = %d, c = %d\n", a, b, c);
    return 0;
}

函数重载至少满足下面的一个条件:
1.参数个数不同
2.参数类型不同
3.参数顺序不同

int func(int a, const char* s) {
    return a;
}
int func(const char* s, int a) {
    return strlen(s);
}
int main() {
    func(1, "abcdef");//会调用哪个?第一个
    func("abcdef", 1);//会调用第二个
    return 0;
}

当函数默认参数遇上函数重载会发生什么?会遇上二义性。

int func(int a, int b, int c = 0) {
    return a + b + c;
}
int func(int a, int b) {
    return a + b;
}
int main() {
    func(1, 2);//会调用哪一个?存在二义性,调用失败。
    return 0;
}

4 函数的升级-下_第1张图片
规则:当要用默认函数参数时,不要使用重载。当要使用重载时,不要使用函数默认参数。

C++编译器调用重载函数的准则

1.编译器会将所有同名函数作为候选者
2.尝试寻找可行的候选函数
2.1精确匹配实参(参数个数和类型)
2.2通过默认参数能够匹配实参
2.3通过默认类型转换匹配实参
3.匹配失败
3.1最终寻找到的可行候选函数不唯一、则出现二义性,编译失败。
3.2无法匹配所有候选者,函数未定义,编译失败。

重载函数的注意事项

  • 重载函数在本质上是相互独立的不同函数
  • 重载函数的函数类型是不同的
  • 函数返回值不能作为函数重载的依据,返回值不同不能作为重载函数。
    函数重载时由函数名和参数列表决定的。

函数重载与函数指针

下面程序哪个函数将被调用:

#include 
#include 
int func (int a) {
    return a;
}
int func(int a, int b) {
    return a + b;
}
int func(const char* s) {
    return strlen(s);
}
typedef int(*PFUNC)(int a);
//typedef void(*PFUNC)(int a); 无法匹配,编译报错。
int main(int argc, char *argv[])
{
	PFUNC p = func;
	p(1);//会调用哪个函数?
	printf("p(1) = %d\n", p(1));
    return 0;
}

当使用函数重载函数名对函数指针进行赋值时:

  • 根据重载规则挑选与函数指参数列表一致的候选者
  • 严格匹配候选者的函数类型与函数指针的函数类型
    依据上述规则,*typedef int(*PFUNC)(int a);*会去匹配第一个函数。

c++和c的相互调用

在项目中,融合c++和c代码是实际工程中不可避免的,虽然c++编译器能够兼容c语言的编译方式,但是c++编译器会优先使用c++的方式进行编译。利用extern关键字,可以强制让c++编译器对代码以c方式进行编译。
范例:C++调用C函数
4 函数的升级-下_第2张图片
范例:C调用C++函数
4 函数的升级-下_第3张图片

统一的解决方案
__cplusplus 是c++编译器内置的标准宏定义,可以让c代码既可以通过c编译器的编译,也可以在c++编译器中意c方式编译

#ifdef __cplusplus
extern "C" {
#endif
//函数声明
#ifdef __cpulsplus
}
#endif

注意,C++编译器不能以C的方式编译多个重载函数。C语言不允许重名函数,C语言没有重载函数概念。
下面代码会编译报错,报函数重名。

#ifdef __cplusplus
extern "C" {
#endif
void f() {
}
void f(int x) {
}
#ifdef __cplusplus
}
#endif

小结

  • 函数重载时C++相对于C语言的一个重要升级。
  • 函数重载通过函数参数列表区分不同的同名函数。
  • 函数的返回值类型不是函数重载的依据,即同名同参的函数,返回值不同,不是函数重载,会编译报错。
  • extern关键字能够实现C和C++相互调用。 C和C++并不对立,可以同时存在于项目中。

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