在本文中,您將學(xué)習(xí)C ++中的模板。您將學(xué)習(xí)如何使用模板的功能進(jìn)行通用編程。
模板是C ++的強(qiáng)大功能,可讓您編寫通用程序。簡(jiǎn)而言之,您可以使用模板創(chuàng)建一個(gè)函數(shù)或一個(gè)類來(lái)處理不同的數(shù)據(jù)類型。
模板通常在較大的代碼庫(kù)中使用,目的是實(shí)現(xiàn)代碼的可重用性和程序的靈活性。
模板的概念可以兩種不同的方式使用:
函數(shù)模板
類模板
函數(shù)模板的工作方式與普通函數(shù)相似,只是有一個(gè)不同之處。
單個(gè)函數(shù)模板可以一次處理不同的數(shù)據(jù)類型,但是單個(gè)普通函數(shù)只能處理一組數(shù)據(jù)類型。
通常,如果需要對(duì)兩種或更多種類型的數(shù)據(jù)執(zhí)行相同的操作,則可以使用函數(shù)重載來(lái)創(chuàng)建具有所需函數(shù)聲明的兩個(gè)函數(shù)。
但是,更好的方法是使用函數(shù)模板,因?yàn)槟梢允褂幂^少的代碼來(lái)執(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ù)來(lái)接受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
在此程序中,不是通過(guò)傳遞值來(lái)調(diào)用函數(shù),而是通過(guò)引用進(jìn)行調(diào)用。
Swap()函數(shù)模板接受兩個(gè)參數(shù),并通過(guò)引用交換它們。
與函數(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ì)算器操作并顯示輸出。