在本文中,您將學(xué)習(xí)C ++中的模板。您將學(xué)習(xí)如何使用模板的功能進(jìn)行通用編程。
模板是C ++的強(qiáng)大功能,可讓您編寫通用程序。簡(jiǎn)而言之,您可以使用模板創(chuàng)建一個(gè)函數(shù)或一個(gè)類來處理不同的數(shù)據(jù)類型。
模板通常在較大的代碼庫中使用,目的是實(shí)現(xiàn)代碼的可重用性和程序的靈活性。
模板的概念可以兩種不同的方式使用:
函數(shù)模板
類模板
函數(shù)模板的工作方式與普通函數(shù)相似,只是有一個(gè)不同之處。
單個(gè)函數(shù)模板可以一次處理不同的數(shù)據(jù)類型,但是單個(gè)普通函數(shù)只能處理一組數(shù)據(jù)類型。
通常,如果需要對(duì)兩種或更多種類型的數(shù)據(jù)執(zhí)行相同的操作,則可以使用函數(shù)重載來創(chuàng)建具有所需函數(shù)聲明的兩個(gè)函數(shù)。
但是,更好的方法是使用函數(shù)模板,因?yàn)槟梢允褂幂^少的代碼來執(zhí)行相同的任務(wù)。
函數(shù)模板以關(guān)鍵字template開頭,其后是<>內(nèi)的模板參數(shù),然后是函數(shù)聲明。
template <class T> T someFunction(T arg) { ... .. ... }
在上面的代碼中,T是一個(gè)模板參數(shù),它接受不同的數(shù)據(jù)類型(如int,float等),而class是關(guān)鍵字。
在上面的示例中,您還可以使用關(guān)鍵字typename代替class。
當(dāng)將數(shù)據(jù)類型的參數(shù)傳遞給someFunction()時(shí),編譯器會(huì)為給定數(shù)據(jù)類型生成someFunction()的新版本。
程序使用函數(shù)模板顯示兩個(gè)數(shù)字中最大的一個(gè)。
//如果將兩個(gè)字符傳遞給函數(shù)模板,則顯示ASCII值較大的字符。 #include <iostream> using namespace std; // template function template <class T> T Large(T n1, T n2) { return (n1 > n2) ? n1 : n2; } int main() { int i1, i2; float f1, f2; char c1, c2; cout << "輸入兩個(gè)整數(shù):\n"; cin >> i1 >> i2; cout << Large(i1, i2) <<" 更大。" << endl; cout << "\n輸入兩個(gè)浮點(diǎn)數(shù):\n"; cin >> f1 >> f2; cout << Large(f1, f2) <<" 更大。" << endl; cout << "\n輸入兩個(gè)字符:\n"; cin >> c1 >> c2; cout << Large(c1, c2) << " 具有較大的ASCII值。"; return 0; }
輸出結(jié)果
輸入兩個(gè)整數(shù): 5 10 10 is larger. 輸入兩個(gè)浮點(diǎn)數(shù): 12.4 10.2 12.4 is larger. 輸入兩個(gè)字符: z Z z 具有較大的ASCII值。
在上面的程序中,定義了一個(gè)函數(shù)模板Large(),它接受數(shù)據(jù)類型為T的兩個(gè)參數(shù)n1和n2。T表示這個(gè)參數(shù)可以是任何數(shù)據(jù)類型。
Large()函數(shù)使用簡(jiǎn)單的條件操作返回兩個(gè)參數(shù)中最大的一個(gè)。
在main()函數(shù)內(nèi)部,聲明了三種不同數(shù)據(jù)類型的變量:int,float和char。 然后將變量作為普通函數(shù)傳遞給Large()函數(shù)模板。
在運(yùn)行時(shí),將整數(shù)傳遞給模板函數(shù)時(shí),編譯器知道必須生成一個(gè)Large()函數(shù)來接受int參數(shù),并且也是這樣做的。
同樣,當(dāng)傳遞浮點(diǎn)數(shù)據(jù)和char數(shù)據(jù)時(shí),它知道自變量數(shù)據(jù)類型并相應(yīng)地生成Large()函數(shù)。
這樣,僅使用一個(gè)函數(shù)模板即可替換三個(gè)相同的常規(guī)函數(shù),并使您的代碼更少也更容易維護(hù)。
程序使用函數(shù)模板交換數(shù)據(jù)。
#include <iostream> using namespace std; template <typename T> void Swap(T &n1, T &n2) { T temp; temp = n1; n1 = n2; n2 = temp; } int main() { int i1 = 1, i2 = 2; float f1 = 1.1, f2 = 2.2; char c1 = 'a', c2 = 'b'; cout << "在將數(shù)據(jù)傳遞給函數(shù)模板之前。\n"; cout << "i1 = " << i1 << "\ni2 = " << i2; cout << "\nf1 = " << f1 << "\nf2 = " << f2; cout << "\nc1 = " << c1 << "\nc2 = " << c2; Swap(i1, i2); Swap(f1, f2); Swap(c1, c2); cout << "\n\n將數(shù)據(jù)傳遞給函數(shù)模板后。\n"; cout << "i1 = " << i1 << "\ni2 = " << i2; cout << "\nf1 = " << f1 << "\nf2 = " << f2; cout << "\nc1 = " << c1 << "\nc2 = " << c2; return 0; }
輸出結(jié)果
在將數(shù)據(jù)傳遞給函數(shù)模板之前。 i1 = 1 i2 = 2 f1 = 1.1 f2 = 2.2 c1 = a c2 = b 將數(shù)據(jù)傳遞給函數(shù)模板后。 i1 = 2 i2 = 1 f1 = 2.2 f2 = 1.1 c1 = b c2 = a
在此程序中,不是通過傳遞值來調(diào)用函數(shù),而是通過引用進(jìn)行調(diào)用。
Swap()函數(shù)模板接受兩個(gè)參數(shù),并通過引用交換它們。
與函數(shù)模板一樣,您也可以為通用類操作創(chuàng)建類模板。
有時(shí),您需要一個(gè)適用于所有類的類實(shí)現(xiàn),只是所使用的數(shù)據(jù)類型不同。
通常,您需要為每種數(shù)據(jù)類型創(chuàng)建一個(gè)不同的類,或者在一個(gè)類中創(chuàng)建不同的成員變量和函數(shù)。
這將會(huì)增加很類似的代碼,并且將難以維護(hù)。
但是,類模板使對(duì)所有數(shù)據(jù)類型重復(fù)使用相同的代碼變得更容易。
template <class T> class className { ... .. ... public: T var; T someOperation(T arg); ... .. ... };
在上面的聲明中,T是模板參數(shù),它是所使用數(shù)據(jù)類型的占位符。
在類內(nèi)部,成員變量var和成員函數(shù)someOperation()均為T類型。
要?jiǎng)?chuàng)建類模板對(duì)象,需要在創(chuàng)建時(shí)在< >中定義數(shù)據(jù)類型。
className<dataType> classObject;
例如:
className<int> classObject; className<float> classObject; className<string> classObject;
程序使用類模板對(duì)兩個(gè)數(shù)字進(jìn)行加,減,乘和除運(yùn)算
#include <iostream> using namespace std; template <class T> class Calculator { private: T num1, num2; public: Calculator(T n1, T n2) { num1 = n1; num2 = n2; } void displayResult() { cout << "Numbers are: " << num1 << " and " << num2 << "." << endl; cout << "Addition is: " << add() << endl; cout << "Subtraction is: " << subtract() << endl; cout << "Product is: " << multiply() << endl; cout << "Division is: " << divide() << endl; } T add() { return num1 + num2; } T subtract() { return num1 - num2; } T multiply() { return num1 * num2; } T divide() { return num1 / num2; } }; int main() { Calculator<int> intCalc(2, 1); Calculator<float> floatCalc(2.4, 1.2); cout << "Int results:" << endl; intCalc.displayResult(); cout << endl << "Float results:" << endl; floatCalc.displayResult(); return 0; }
輸出結(jié)果
Int results: Numbers are: 2 and 1. Addition is: 3 Subtraction is: 1 Product is: 2 Division is: 2 Float results: Numbers are: 2.4 and 1.2. Addition is: 3.6 Subtraction is: 1.2 Product is: 2.88 Division is: 2
在上面的程序中,聲明了一個(gè)類模板Calculator。
該類包含兩個(gè)類型為T的私有成員:num1和num2,以及用于初始化成員的構(gòu)造函數(shù)。
它還包含公共成員函數(shù),用于計(jì)算數(shù)字的加,減,乘和除,以返回用戶定義的數(shù)據(jù)類型的值。 同樣,函數(shù)displayResult()將最終結(jié)果輸出顯示到屏幕上。
在main()函數(shù)中,分別為數(shù)據(jù)類型創(chuàng)建了兩個(gè)不同的Calculator對(duì)象intCalc和floatCalc:int和float。 使用構(gòu)造函數(shù)初始化值。
注意,我們?cè)趧?chuàng)建對(duì)象時(shí)使用<int>和<float>。這些告訴編譯器用于類創(chuàng)建的數(shù)據(jù)類型。
這將為int和float分別創(chuàng)建一個(gè)類定義,然后相應(yīng)地使用它們。
然后,displayResult()兩個(gè)對(duì)象都被調(diào)用,
然后,調(diào)用這兩個(gè)對(duì)象的displayResult(),它執(zhí)行計(jì)算器操作并顯示輸出。