[C++]缺省值和函数重载
1. 缺省值
1.1. 缺省值概念
缺省参数是声明或定义函数时为函数参数指定一个缺省值。在调用该函数时,如果没有指定形参则采用该形参的缺省值,否则使用指定的实参。
带有缺省值参数的函数代码:
#include<iostream>usingnamespacestd;//缺省值函数voidFunc1(constchar*str="Func1")//默认参数str指向字符串常量"Func1"{cout<<str<<endl;}intmain(){Func1();//不传入参数则采用该形参的缺省值"Func1"Func1("I can rewind time!");//如果指定了实参则采用指定了的参数return0;}代码运行结果:
Func1 I can rewind time!1.2. 缺省值参数的分类
1.2.1. 全缺省参数
#include<iostream>usingnamespacestd;//全缺省//默认立方体的长宽高都为1voidbox(doublelength=1,doublewidth=1,doubleheight=1){cout<<"长:"<<length<<endl;cout<<"宽:"<<width<<endl;cout<<"高:"<<height<<endl;cout<<endl;}intmain(){box();box(10);//length指定了实参 另外两个为缺省值box(10,20);//lenght和widht指定了实参 heihgt为缺省值box(10,20,30);//三个都指定了实参,缺省值不使用return0;}代码运行结果:
长:1 宽:1 高:1 长:10 宽:1 高:1 长:10 宽:20 高:1 长:10 宽:20 高:301.2.2. 半缺省参数
#include<iostream>usingnamespacestd;//半缺省参数//立方体的高度默认为10 长度和宽度需要指定形参voidbox1(doublelength,doublewidth,doubleheight=10){cout<<"长:"<<length<<endl;cout<<"宽:"<<width<<endl;cout<<"高:"<<height<<endl;cout<<endl;}intmain(){//box1(); //错误,需要指定两个形参//box1(10); //错误,需要指定两个形参box1(10,20);//lenght和widht指定了实参 heihgt为缺省值box1(10,20,30);//三个都指定了实参,缺省值不使用return0;}代码运行结果:
长:10 宽:20 高:10 长:10 宽:20 高:301.3. 注意事项
- 函数的声明与定义分离时,缺省值只需在声明时给出。如果声明和定义都给出了缺省值,编译器无法知道要使用哪一边的缺省值,会导致编译报错。
- 半缺省值只能从函数参数的右边到左边依次给出,不能从左到右给或者是间隔着给,函数传参时也不能间隔着传。
- 缺省值必须是全局变量或常量。
- C语言编译器不支持缺省值。
2. 函数重载
2.1. 函数重载的概念
C++允许同一函数名定义多个函数,而这些函数的参数个数、参数类型、参数的顺序和返回值可以不相同。这就是函数重载(function overloading) 。 即对一个函数名重新赋予它的新的含义,使一个函数名可以多用。所谓重载,其实就是“一物多用”。
2.2. 函数的重载条件
2.2.1. 参数的类型的不同
#include<iostream>usingnamespacestd;//函数的参数类型不同//两种不同类型的加法运算函数//如果Add传入的是两个int类型的参数则执行下面这个函数intAdd(intx1,intx2){returnx1+x2;}//如果Add传入的是两个double类型的参数则执行下面这个函数doubleAdd(doublex1,doublex2){returnx1+x2;}intmain(){inti1=5,i2=6;doubled1=5.6,d2=6.5;cout<<i1<<" + "<<i2<<" = "<<Add(i1,i2)<<endl;cout<<d1<<" + "<<d2<<" = "<<Add(d1,d2)<<endl;return0;}运行结果:
5 + 6 = 11 5.6 + 6.5 = 12.12.2.2. 参数的个数不同
#include<iostream>usingnamespacestd;//参数的个数不同voidFunc2(){cout<<"Func2()"<<endl;}voidFunc2(inta){cout<<"Func2(int a)"<<endl;}voidFunc2(inta,intb){cout<<"Func2(int a,int b)"<<endl;}intmain(){Func2();Func2(1);Func2(1,2);return0;}运行结果:
Func2() Func2(int a) Func2(int a,int b)2.2.3. 参数的顺序不同
#include<iostream>usingnamespacestd;//当参数的个数和类型都相同时//参数的顺序不同voidFunc3(inta,doubleb){cout<<"Func3(int a,double b)"<<endl;}voidFunc3(doublea,intb){cout<<"Func3(double a,int b)"<<endl;}intmain(){inta=0;doubleb=0;Func3(a,b);Func3(b,a);return0;}运行结果:
Func3(inta,doubleb)Func3(doublea,intb)2.3. 注意事项
- 函数的重载必须满足上述的三个条件之一:参数的类型、个数、顺序不同。
- 函数重载会存在二义性问题。
- C语言编译器不支持函数重载。
二义性问题例子:
#include<iostream>using namespace std;//函数重载的二义性问题intAdd(int x1,int x2){returnx1+x2;}//如果Add传入的是两个double类型的参数则执行下面这个函数doubleAdd(double x1,double x2){returnx1+x2;}intmain(){int a=5;double b=5.5;Add(a,b);//这里传入的是整形的a和双精度类型的breturn0;}出现编译报错:
有多个 重载函数 "Add" 实例与参数列表匹配: “Add”: 重载函数具有类似的转换原因是这里传入的参数对执行的重载函数存在二义性。
变量a是整形,而变量b是双精度性,如果我们将其混合传入Add函数中,Add的两个重载函数都可以接收a和b来执行对应操作, 因为int类型和double类型存在隐式类型转换。编译器分不清用户具体想执行的是哪个重载的Add函数,就会产生二义性,从而发生编译报错。
代码示例存在的二义性:
- 编译器将
int a隐式类型转化为double型,则执行Add(double, double)这个函数 - 编译器将
double b隐式类型转化为int型,则执行Add(int, int)这个函数
解决办法是在传入参数时对a或b进行显式强制类型转化消除二义性 ,修改代码如下:
#include<iostream>using namespace std;//函数重载的二义性问题intAdd(int x1,int x2){returnx1+x2;}//如果Add传入的是两个double类型的参数则执行下面这个函数doubleAdd(double x1,double x2){returnx1+x2;}intmain(){int a=5;double b=5.5;//Add(a, b);//这里传入的是整形的a和双精度类型的b//显式强制类型转化cout<<Add(double(a),b)<<endl;cout<<Add(a,int(b))<<endl;return0;}运行结果:
10.5 10