函数的升级(下)-函数的重载

对于函数的升级,这一章主要讲函数重载。在说函数重载之前,先想想我们自然语言中的一些词汇。这对于理解函数重载有一定的帮助。

一、自然语言

我们平时生活中所说的语言就是自然语言,在自然语言中,我们经常用同样的字搭配不同的词汇来表达不同的意思,比如:洗衣服、洗车、洗脸、洗马桶、洗脑。能和‘洗’字搭配的词汇有很多,但是它和不同的词汇搭配在一起就有这不同的含义,同样的‘洗’字,我们所表达的意思的动作是不同的。这就是重载。
重载(Overload):同一个标识符在不同的上下文有不同的意义;
如:‘洗’字和不同的词汇搭配有不同的含义,‘paly’和不同的单词搭配有不同的含义;
重载在自然语言中是随处可见的,那么程序设计中是否也有重载呢?
当然是有的,在C++中就有函数重载的概念。

二、函数重载

函数重载:用同一个函数名定义不同的函数,当函数名和不同的参数搭配时函数的含义不同。
例如:

int func(int x)
{
    return x;
}

int func(int a,int b)
{
    return a + b;
}

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

在C++中,函数重载至少满足下面的一个条件:
1、参数个数不同;
2、参数类型不同;
3、参数类型顺序不同;
当函数默认参数遇上函数重载时,在调用函数时可能出现二义性,这样将导致编译失败。
比如:

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[])
{
    func(1,2);//调用哪一个?
    return a+b;
}

在上面的代码中,main函数中的func到底该调用哪一个呢?将函数调用理解为两个参数,调用int func(int a,int b),将函数调用理解为两个参数加一个默认参数可以调用int func(int a,int b,int c= 0),这就出现了二义性。当编译器编译到这里时,它也不知道到底该调用哪一个,所以它将报错。
编译器调用重载函数的准则:
1、将所有同名函数作为候选者
2、尝试寻找可行的候选函数
(1)精确匹配实参
(2)通过默认参数能够匹配实参
(3)通过默认类型转换匹配实参
从上面的源码看,前两个的优先级是相同的;最后一个的优先级比前两个低;

int func(int a)
{
    return a * a;
}
int func(char a)
{
    return a - '0';
}
int main(int argc,char *argv[])
{
    int val = fuc('3');
}

在上面的代码中,我们可以看出函数调用的是int func(char a)函数,它并没有进行默认转换去调用int func(int a)。所以说(3)的优先级比(1)低,当它有精准匹配时,并不进行默认转换匹配。
3、匹配失败
(1)最终寻找到的可行候选函数不唯一,则出现二义性,编译失败。
(2)无法匹配所有候选者,函数未定义,编译失败。
函数重载的注意事项:
1、重载函数在本质上是相互独立的不同函数;
2、重载函数的函数类型是不同的;
3、函数返回值不能作为函数重载的依据;
4、函数重载是由函数名和参数列表决定的;
函数重载与函数指针:
当使用重载函数名对函数指正进行赋值时,怎么赋值呢?
C++编译器根据以下规则进行赋值:
根据从在规则挑选与函数指针参数列表一致的候选者;
严格匹配候选者的函数类型与函数指针的函数类型;

三、C和C++的相互调用

在现代工程当中融合C++和C代码是不可避免的,虽然C++编译器能够兼容C语言的编译方式,但C++编译器会优先使用C++的方式进行编译,那怎么融合C++和C代码呢?
利用extern关键字强制让C++编译器对代码进行C方式编译。
在C++中调用C代码:
假设用C语言写了一个函数:

int add(int a,int b)
{
    return a+b;
}

并将这个函数的声明放入add.h头文件下,并将C代码编译成“.o“文件。在C++的主函数里调用这个函数,应这样写:

#include <stdio.h>
extern "C"{
#include "add.h"
}
int main(int argc,char *argv[])
{
    printf("1+2 = %d\n",add(1,2));
    return 0;
}

这样就能让C++编译器用C编译器的方式编译#include “add.h”中的代码,这样就能将C代码融合进C++中了。
在C中调用C++代码:
将所有的C++代码以C编译器方式编译,在C代码中调用C++代码。当然既然要用C编译器的方式编译C++代码,它就不能支持函数重载和一些C++的特性。
统一的解决方案:
C++编译器内置了__cplusplus标准宏定义,它的意义是,让C代码即可以通过C编译器的编译,也可以在C++编译器中以C方式编译。模板如下:

#ifdef __cplusplus
extern "C" {
#endif

    /*C代码*/

#ifdef __cplusplus
}
#endif

四、小结

1、函数重载是C++对C语言的一个重要升级
2、函数重载通过函数参数列表区分不同的同名函数
3、函数的返回值类型不是函数重载的依据
4、extern关键的关键能够实现C和C++的相互调用
C和C++并不队里,可以同时存在于项目中!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值