C++基礎 004(用衣服搭配類比理解)函數重載

C++中的函數重載(Overroad)

/*
 *運行平臺:Visual Studio 2015(Debug x86)
 *參考資料:《C++ Primer Plus(第6版)》,傳智掃地增C++基礎課程

*/


一、前言

  俗話說,人靠衣裝馬靠鞍,一套好看的衣服搭配可以讓人煥然一新。
  同理,一套合理的函數重載也可以使編譯器更好的根據數據類型處理問題
  我們可以通過每天的衣服搭配 類比 函數重載,即一個星期中可以根據星期幾,搭配不同的衣服方案

實物 類比爲
人的性格 函數返回值
人的名字 函數名
每天的衣服搭配方案 參數列表
衣服件數 參數個數
衣服款式 參數的數據類型

在這裏插入圖片描述

二、概念

  重載函數是函數的一種特殊情況,爲方便使用,C++允許在同一範圍中聲明幾個功能類似同名函數,但是這些同名函數的形式參數(指參數的個數、類型或者順序)必須不同,也就是說用同一個函數完成不同的功能
  總結:

  1. 用同一個函數名定義不同的函數——一個人每天可以搭配不同的衣服。
  2. 當函數名和不同的參數搭配時函數的含義不同——衣服的搭配,隨每天的變化而變化。

二、如何使用

1、滿足條件

函數重載至少滿足下面的一個條件:

  1. 參數個數不同——衣服件數不同
  2. 參數類型不同——衣服款式不同
  3. 參數順序不同(同時類型不同)——疊穿衣服效果

2、使用方法

2.1 參數個數不同——衣服件數不同

  • 代碼如下:
void fun (int a)
{
	cout << a << endl;
}

void fun (int a, int b)
{
	cout << a << b << endl;
}

void main()
{
	int a = 0;
	int b = 1;

	fun(a);
	fun(a,b);
	system("pause");
}
  • 運行結果:
    通過調用函數時的參數個數不同,來執行不同的重載函數——通過穿衣件數,別人(編譯器)來判斷今天搭配的是哪套衣服。
    在這裏插入圖片描述

2.2 參數類型不同——衣服款式不同

  • 代碼如下:
void fun (int a)
{
	cout << a << endl;
}

void fun (char a)
{
	cout << a << endl;
}

void main()
{
	int a = 0;
	char b = 'b';

	fun(a);
	fun(b);
	system("pause");
}
  • 運行結果:
    通過調用函數時的參數類型不同,來執行不同的重載函數——通過穿衣的款式,別人(編譯器)就可以來判斷今天搭配的是哪套衣服。
    在這裏插入圖片描述

2.3 參數順序不同(同時類型不同)——疊穿衣服效果

  • 代碼如下:
void fun(int a, char b)
{
   cout << a << b << endl;
}

void fun(char a, int b)
{
   cout << a << b << endl;
}

void main()
{
   int a = 0;
   char b = 'b';

   fun(a, b);
   fun(b, a);
   system("pause");
}
  • 運行結果:
    通過調用函數時的參數順序(同時類型)不同,來執行不同的重載函數——通過穿衣的順序(相當於疊穿衣服會呈現不同的效果),別人(編譯器)來判斷今天搭配的是哪套衣服。
    在這裏插入圖片描述

3、注意:函數返回值不是函數重載的判斷標準

前提:參數列表(個數,類型和順序)都一致。

  • 代碼如下:
void fun(int a, char b)
{
	cout << a << b << endl;
}

int fun(int a, char b)
{
	cout << a << b << endl;
	return 0;
}
  • 運行結果:
    此時在你定義完函數時,編譯器就會報錯——當你前後兩天搭配的衣服款式一樣時,就算性格此時不同,但是在別人(編譯器)看來,人還是和昨天的人一樣。
    在這裏插入圖片描述

三、難點一:重載函數和默認函數參數混搭

  前面我們說過當參數個數不同時,可以重載函數,可是如果出現重載函數和默認函數參數混搭的情況,可以重載成功嗎?
通過實驗證明:

  • 代碼如下:
void fun(char a)
{
	cout << a << endl;
}

void fun(int a, int b = 0)
{
	cout << a << b << endl;
}

void main()
{
	int a = 0;

	fun(a);
	system("pause");
}
  • 運行結果:
    在程序編譯時,編譯器會報錯。
    在這裏插入圖片描述

這個一種特殊情況,千萬記住在編程時不要出現這個錯誤。

四、難點二: 重載函數和函數指針

1、驗證

當使用重載函數名對函數指針進行賦值時,編譯器是如何挑選重載函數的?
通過實驗證明:

  • 代碼如下
void fun(int a)
{
	cout << a << endl;
}

void fun(int a,int b)
{
	cout << a << b << endl;
}

//聲明一個函數指針類型 
typedef void(*MyFun2) (int a);

void main()
{
	int a = 1;
	int b = 2;
 	MyFun2 p = fun;

	p(a);
	system("pause");
}
  • 運行結果:
    可以看到程序運行了void fun(int a);這個重構函數。
    在這裏插入圖片描述
    我們嘗試下把p(a); 改爲 p(a, b);,可以看到在程序編寫完後,提示錯誤。
    在這裏插入圖片描述

2、總結

當使用重載函數名對函數指針進行賦值:

  • 根據重載規則挑選函數指針參數列表一致的候選者
  • 嚴格匹配候選者的函數類型函數指針的函數類型

五、編譯器調用重載函數的準則

  1. 尋找:將所有同名函數作爲候選者,嘗試尋找可行的候選函數。
  2. 精確匹配實參:通過默認參數能夠匹配實參 和 通過默認類型轉換匹配實參
  3. 匹配成功:執行對應的重載函數。
  4. 匹配失敗:最終尋找到的可行候選函數不唯一,則出現二義性,編譯失敗;無法匹配所有候選者,函數未定義,編譯失敗。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章