C++学习笔记--函数重载

重载的意思是什么?就是同一个标识符在不同上下文中发挥不同的作用,比如‘洗’这个字,配上不同的事物就代表不同的意义,洗衣服、洗脸等等。从平时生活中的自然语言我们可以延伸到程序语言中,即对函数进行重载。

函数重载

函数重载就是用同一个函数名定义不同的函数,当同一个函数名和不同参数列表搭配时函数的意义不同。

int func(int x)
{
	return x;
}

int func(int x,int y)
{
	return x+y;
}

int func(const char *s)
{
	return strlen(s);
}

上面三个函数的函数名都是func,但是他们的参数列表不同,所以在函数重载的机制中他们是不同的函数。那么我们在写程序时需要满足什么条件才能实现函数重载呢?

1、参数个数不同

2、参数类型不同

3、参数顺序不同

三个条件中,只要几个同名函数满足至少一个条件就能构成函数重载。可以参考上面三个函数进行理解。

思考一个问题,当函数重载遇上函数默认参数会发送什么?

int func(int x,int y,int z = 0)
{
	return x+y+z;
}

int func(int x,int y)
{
	return x+y;
}

int main(int argc,int char** argv)
{
	int c = func(1,2);//编译器会知道调用的是谁吗?
	return 0;
}

当我们进行编译时编译器会报出“”call of overload 'func(int, int)'is ambiguous“”的错,提示我们调用的重载函数是模糊的。同样我们写程序的人会知道调用的是哪一个函数吗?答案肯定是无法确定的,所以此处产生了二义性,编译器是肯定也是无法识别的。

讲过构成重载的条件,那我们讲讲调用重载函数的准则:

1、首先编译器会将所有同名函数作为候选函数

2、寻找可行的候选函数

精确匹配实参,包括类型,个数,顺序

通过默认参数能够匹配实参

通过默认类型转换匹配实参

3、最终存在多个候选函数能够匹配那么表示出现二义性,编译失败;无法匹配所有候选者,函数未定义,编译也会失败。

函数重载的注意事项:

1、重载函数在本质上是相互独立的不同函数编译器在对重载函数进行编译过后生成的是不同的标识符,用于函数调用时区分不同函数。

2、重载函数的函数类型不同,我们知道函数类型是由参数列表和返回值类型共同决定的,重载函数的参数列表必然不同,所以重载函数的类型也绝对不同。

3、函数的返回值不能作为函数重载的判断依据,函数重载只由函数名和参数列表共同决定

4、不能直接通过函数名获取函数的地址,重载函数名都是相同的,所以没有意义,而且编译也会出错。

        printf("%p\n", (int(*)(int, int))add);
        printf("%p\n", (int(*)(int, int, int))add);//这种方式却是可以的。

5、C++中通过函数名和参数列表确定函数调用。

重载与函数指针

在将重载函数名赋值给函数指针时,根据重载规则挑选与函数指针参数列表一致的候选者,严格匹配候选者的函数类型与函数指针的函数类型。比如前面获取函数地址会将其强制类型转换成与对应重载函数匹配的函数指针类型。需要注意的是函数重载必然发生在同一个作用域中,因为C++中全局作用域和类作用域都能进行函数重载。在函数重载构造和调用中我们没有将函数返回值类型作为挑选规则,但是在重载函数与函数指针中编译器需要用参数列表或参数类型(参数列表和返回值类型)进行函数选择。

C++和C相互调用

实际工程中虽然C++兼容C代码,但是偶尔往往会使用一些第三方提供的C的库,这样我们就需要在C++中进行C编译了。但是总有解决的方法的,extern关键字就能强制让C++编译器进行C方式的编译。

extern "c"

{

...

...

//此处包含的就是C++对C的调用

}

但是有一点需要提出来,C++虽然能包含C编译,但是C编译器是不能编译C++的,这样的话我们的程序就只能在C++中编译了,要是我们想让一个程序既能在C++中编译又能在C编译器中编译的话那该怎么办?办法当然是有的,使用C++编译器的内置的标准宏定义__cpiusplus即可。

#ifdef __cplusplus
extern "C" {
#endif

#include "add.h"//需要编译的文件

#ifdef __cplusplus
}
#endif
这样如果是在C中编译就会按照C方式编译,否则就是C++的编译方式。

最后一点,C++编译器不能以C的方式编译重载函数,因为编译方式决定函数名被编译后的目标名,C++中将函数名和参数列表编译成目标名,C中只将函数名作为目标名进行编译,所以,编译方式决定符号表的函数名的最终目标名。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值