1. 程式人生 > >C++入門筆記--函式的過載

C++入門筆記--函式的過載

函式過載的實質就是用同樣的名字再定義一個有著不同引數但有著同樣用途的函式(類似於人格分裂,多重身份),可以是引數個數的不同,也可以是引數資料型別上的不同

例子:

用的還是上個筆記裡的東西,現在我把主要的轉換步驟寫在了一個函式裡,並且重新定義了一個同名的但是引數型別不同的引數,在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類裡對這兩個符號進行了過載。

函式過載需要注意的內容:

  1. 對函式(方法)進行過載時一定要謹慎,不要“無的放矢”或“亂點鴛鴦譜”,尤其是引數型別不同的時候,確保你想呼叫函式的形參型別與你定義的一致。
  2. 要知道過載函式越多,該程式就越不容易看懂.......
  3. 注意區分過載和覆蓋(覆蓋在後面的筆記裡會有)
  4. 我們只是可以通過不同引數進行過載,但不能通過不同的返回值對函式進行過載(儘管後者也是一種區別)
  5. 對函式進行過載的目的是為了方便對不同資料型別進行同樣的處理。

練手題目:

//利用過載函式的方法 設計一個程式 該程式通過函式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;
}

執行結果: