函数重载的实质就是用同样的名字再定义一个有着不同参数但有着同样用途的函数(类似于人格分裂,多重身份),可以是参数个数的不同,也可以是参数数据类型上的不同
例子:
用的还是上个笔记里的东西,现在我把主要的转换步骤写在了一个函数里,并且重新定义了一个同名的但是参数类型不同的参数,在main里我两次输入数据,一次是double一次是int,并调用函数这个名字的函数,我们想的是不同的参数类型应该根据参数的不同调用不同的函数。结果如下:
//编写一个温度单位转换程序 提示用户以[xx.x C]或[xx.x F]的格式输入
//要求:转换成相应摄氏或者华氏温度输出
#include<iostream>
int main(){
void convertTemperature(double templeIn,char typeIn);
double templeIn;//输入的数值 调用第一个函数
int templeInt;//函数的参数类型不同了 调用第二个参数
char typeIn;//输入的单位类型
std::cout<<"请以【xx.x C】或【xx.x F】的格式输入一个温度:";
std::cin>>templeIn>>typeIn;
std::cin.ignore(10,'\n');//忽略缓冲区内的回车
convertTemperature(templeIn,typeIn);
std::cout<<"请以【xx.x C】或【xx.x F】的格式输入一个温度:";
std::cin>>templeInt>>typeIn;
std::cin.ignore(10,'\n');//忽略缓冲区内的回车
convertTemperature(templeInt,typeIn);
return 0;
}
void convertTemperature(double templeIn,char typeIn){
//华氏温度 = 摄氏温度*9.0/5.0+32 9.0/5.0和32在C语言里可以用define宏定义 但是在这里学习用静态变量
const unsigned short ADD_SUBTRACT = 32;
const double RATIO = 9.0/5.0;//关于const静态变量和define宏定义 各有何好处
double templeOut;
char typeOut;
switch(typeIn){
case 'c':
case 'C':
templeOut = templeIn*RATIO+ADD_SUBTRACT;
typeOut = 'F';
typeIn = 'C';
break;
case 'f':
case 'F':
templeOut = (templeIn-ADD_SUBTRACT)/RATIO;
typeIn = 'F';
typeOut = 'C';
break;
default: typeOut = 'E';//错误信息
}
if(typeOut!='E') std::cout<<templeIn<<typeIn<<"="<<templeOut<<typeOut<<"\n\n";//输入格式正确
else std::cout<<"输入格式有误!"<<'\n';
std::cout<<"请输入任何字符结束程序!\n";
std::cin.ignore(100,'\n');//忽略掉缓冲区的回车
}
void convertTemperature(int templeInt,char typeIn){
const unsigned short ADD_SUBTRACT = 32;
const double RATIO = 9.0/5.0;//关于const静态变量和define宏定义 各有何好处
int templeOut;
char typeOut;
switch(typeIn){
case 'c':
case 'C':
templeOut = templeInt*RATIO+ADD_SUBTRACT;
typeOut = 'F';
typeIn = 'C';
break;
case 'f':
case 'F':
templeOut = (templeInt-ADD_SUBTRACT)/RATIO;
typeIn = 'F';
typeOut = 'C';
break;
default: typeOut = 'E';//错误信息
}
if(typeOut!='E') std::cout<<templeInt<<typeIn<<"="<<templeOut<<typeOut<<"\n\n";//输入格式正确
else std::cout<<"输入格式有误!"<<'\n';
std::cout<<"请输入任何字符结束程序!\n";
std::cin.ignore(100,'\n');//忽略掉缓冲区的回车
}
//结果:
输入:34.2c 输出:34.2C = 93.56F
输入:34c 输出:34C = 93.2F
很显然结果并没有像我们想的一样,只是因为犯了一个错误,在进行函数的声明时,只是声明了第一个函数,而并没有声明跟他参数不同但同名的函数,那当然在调用的时候会把int强制转换成double然后调用第一个函数,所以结果是double,做出的改正就是在家伙是哪个一个第二个函数的声明,完整代码如下:
#include<iostream>
const unsigned short ADD_SUBTRACT = 32;
const double RATIO = 9.0/5.0;
int main(){
void convertTemperature(double templeIn,char typeIn);
void convertTemperature(int templeInt,char typeIn);
double templeIn;
int templeInt;
char typeIn;
std::cout<<"请以【xx.x C】或【xx.x F】的格式输入一个温度:";
std::cin>>templeIn>>typeIn;
std::cin.ignore(10,'\n');
convertTemperature(templeIn,typeIn);
std::cout<<"请以【xx.x C】或【xx.x F】的格式输入一个温度:";
std::cin>>templeInt>>typeIn;
std::cin.ignore(10,'\n');
convertTemperature(templeInt,typeIn);
return 0;
}
void convertTemperature(double templeIn,char typeIn){
double templeOut;
char typeOut;
switch(typeIn){
case 'c':
case 'C':
templeOut = templeIn*RATIO+ADD_SUBTRACT;
typeOut = 'F';
typeIn = 'C';
break;
case 'f':
case 'F':
templeOut = (templeIn-ADD_SUBTRACT)/RATIO;
typeIn = 'F';
typeOut = 'C';
break;
default: typeOut = 'E';
}
if(typeOut!='E') std::cout<<templeIn<<typeIn<<"="<<templeOut<<typeOut<<"\n\n"; else std::cout<<"输入格式有误!"<<'\n';
std::cout<<"请输入任何字符结束程序!\n";
std::cin.ignore(100,'\n');
}
void convertTemperature(int templeInt,char typeIn){
int templeOut;
char typeOut;
switch(typeIn){
case 'c':
case 'C':
templeOut = templeInt*RATIO+ADD_SUBTRACT;
typeOut = 'F';
typeIn = 'C';
break;
case 'f':
case 'F':
templeOut = (templeInt-ADD_SUBTRACT)/RATIO;
typeIn = 'F';
typeOut = 'C';
break;
default: typeOut = 'E';
}
if(typeOut!='E') std::cout<<templeInt<<typeIn<<"="<<templeOut<<typeOut<<"\n\n";
else std::cout<<"输入格式有误!"<<'\n';
std::cout<<"请输入任何字符结束程序!\n";
std::cin.ignore(100,'\n');
}
//输入 34.2c 输出 34.2C = 93.56F
//输入 34c 输出 34C = 93.2F
结果意料之中,十分开心!
这个例子我们可以体验到:对函数进行重载,事实上可以简化编程工作和提高代码的可读性。事实上重载不是真正的面向对象特征(选择题可能会考),他只是可以简化编程工作的一种方案,而简化工作正是C++的全部追求,越是高级语言就越是简化处理工作。
输入输出流时用的<<和>>在C语言里是左移和右移,但在C++里却是流符,原因在在cout和cin类里对这两个符号进行了重载。
函数重载需要注意的内容:
- 对函数(方法)进行重载时一定要谨慎,不要“无的放矢”或“乱点鸳鸯谱”,尤其是参数类型不同的时候,确保你想调用函数的形参类型与你定义的一致。
- 要知道重载函数越多,该程序就越不容易看懂.......
- 注意区分重载和覆盖(覆盖在后面的笔记里会有)
- 我们只是可以通过不同参数进行重载,但不能通过不同的返回值对函数进行重载(尽管后者也是一种区别)
- 对函数进行重载的目的是为了方便对不同数据类型进行同样的处理。
练手题目:
//利用重载函数的方法 设计一个程序 该程序通过函数calc()进行计算并返回显示结果
//-当传入一个参数时 计算该参数的平方值
//-当传入两个参数时 计算该函数的积
//-当传入三个参数时 计算该函数的和
#include<iostream>
using namespace std;
double calc(double num1);
double calc(double num1,double num2);
double calc(double num1,double num2,double num3);
int main(){
double num1,num2,num3;
//重载第一个函数
cout<<"please input a num:";
cin>>num1;
cout<<"\nthe square of the "<<num1<<" is "<<calc(num1);
cin.ignore(10,'\n');//忽略缓冲区的回车
//重载第二个函数
cout<<"\n\nplease input two num:";
cin>>num1>>num2;
cout<<"\nthe product of the "<<num1<<" and "<<num2<<" is "<<calc(num1,num2);
cin.ignore(10,'\n');
//重载第三个函数
cout<<"\n\nplease input three num:";
cin>>num1>>num2>>num3;
cout<<"\nthe add of "<<num1<<" "<<num2<<" "<<num3<<" is "<<calc(num1,num2,num3);
cin.ignore(10,'\n');
}
double calc(double num1){
return num1*num1;
}
double calc(double num1,double num2){
return num1*num2;
}
double calc(double num1,double num2,double num3){
return num1+num2+num3;
}
运行结果: