建設(shè)網(wǎng)站的目的服裝類鎮(zhèn)江網(wǎng)站定制
概述
????????默認(rèn)參數(shù)是C++中新增的特性。在C++中,可以為函數(shù)的參數(shù)指定默認(rèn)值。調(diào)用函數(shù)時,如果沒有指定實參,則自動使用默認(rèn)參數(shù)。默認(rèn)參數(shù)的基本語法這里就不作介紹了,下面重點介紹使用默認(rèn)參數(shù)的一些知識要點。
基本規(guī)則
????????1、當(dāng)函數(shù)中某個形參有默認(rèn)值時,該形參右邊的所有形參都必須有默認(rèn)值。在下面的示例代碼中,形參a有默認(rèn)值,但右邊的形參b沒有默認(rèn)值,這是不合法的,會報編譯錯誤。
int Add(int a = 5, int b, int c = 6);
????????2、只能在函數(shù)聲明和函數(shù)定義其中一處給形參指定默認(rèn)值,不能在兩處同時指定,通常在函數(shù)聲明時指定。比如,下面的示例代碼就是不正確的。
// 函數(shù)定義和聲明時,不同同時指定默認(rèn)參數(shù)值,否則,編譯出錯
int Add(int a = 5, int b = 6);int Add(int a = 5, int b = 6)
{return a + b;
}
????????修改后的代碼如下:
int Add(int a = 5, int b = 6);int Add(int a /* = 5 */, int b /* = 6 */)
{return a + b;
}
????????3、形參的默認(rèn)值可以是常量、常量表達(dá)式、全局變量和函數(shù)指針,但不能是局部變量。因為默認(rèn)值一般在編譯期就會確定下來,而局部變量需要到運行時才能確定其值。
typedef int (*CALLBACK_TEST)(const char *pszText);static int s_nData = 1;int Test(const char *pszText);int Add(int a = 66, int b = 88 + 99, int c = s_nData, CALLBACK_TEST d = Test);
默認(rèn)參數(shù)與占位參數(shù)
????????占位參數(shù)是指參數(shù)只聲明了類型,沒有聲明名稱。由于沒有指定參數(shù)名,在函數(shù)內(nèi)部無法使用占位參數(shù),但調(diào)用函數(shù)時,卻必須給占位參數(shù)指定實參。占位參數(shù)可以與默認(rèn)參數(shù)結(jié)合起來使用,此時可以不傳實參,主要用于程序擴展和對C代碼的兼容。示例代碼如下:
int Test(int a, int = 88)
{return a;
}Test(1);
Test(1, 2);
默認(rèn)參數(shù)與函數(shù)重載
????????在重載的多個函數(shù)中,如果有的函數(shù)指定了默認(rèn)參數(shù),則很容易發(fā)生二義性的問題,導(dǎo)致編譯器無法確定到底使用哪個重載函數(shù),進而發(fā)生編譯錯誤。可參看下面的示例代碼。
class CBase
{
public:void Show(int a){printf("CBase Show: %d\n", a);}void Show(int a, int b = 88){printf("CBase Show: %d, %d\n", a, b);}
};CBase base;
base.Show(66); // 產(chǎn)生二義性,編譯報錯
????????可以看到,調(diào)用base對象的函數(shù)Show(66)時,編譯器不知道該調(diào)用哪一個重載版本的函數(shù),因為兩個版本都能匹配上,故編譯器會報錯。解決該問題的最佳方案為:盡量不要在函數(shù)重載時指定默認(rèn)參數(shù)。
默認(rèn)參數(shù)與虛函數(shù)
????????在有派生關(guān)系的類中,如果基類和派生類的虛函數(shù)中都指定了默認(rèn)參數(shù),且默認(rèn)參數(shù)的值不一致,則會出現(xiàn)一些不符合用戶預(yù)期的結(jié)果。具體可參看下面的示例代碼。
class CBase
{
public:virtual void Show(int a = 66){printf("CBase Show: %d\n", a);}
};class CDerived : public CBase
{
public:virtual void Show(int a = 88){printf("CDerived Show: %d\n", a);}
};CDerived *pDerived = new CDerived();
pDerived->Show(); // 輸出為CDerived Show: 88
CBase *pBase = pDerived;
pBase->Show(); // 輸出為CDerived Show: 66
????????可以看到,調(diào)用函數(shù)時發(fā)生了多態(tài)行為,均調(diào)用了派生類的Show函數(shù),但輸出值不一樣,為什么會這樣呢?我們知道,虛函數(shù)具有多態(tài)行為,是動態(tài)綁定的,但函數(shù)的默認(rèn)參數(shù)卻是在編譯時就靜態(tài)綁定的。使用派生類的指針調(diào)用函數(shù)時,綁定的是派生類中聲明的函數(shù)的默認(rèn)參數(shù)。使用基類的指針調(diào)用函數(shù)時,綁定的是基類中聲明的函數(shù)的默認(rèn)參數(shù)。