1-1 為什麼要一用函數模闆呢。
#include <iostream>
using namespace std;
/*
void myswap(int &a, int &b)
{
int t = a;
a = b;
b = t;
}
void myswap(char &a, char &b)
{
char t = a;
a = b;
b = t;
}
*/
//template 關鍵字告訴C++編譯器 我要開始泛型了.你不要随便報錯
//資料類型T 參數化資料類型
template <typename T>
void myswap(T &a, T &b)
{
T t;
t = a;
a = b;
b = t;
}
void main()
{
//char a = 'c';
int x = ;
int y = ;
myswap(x, y); //自動資料類型 推導的方式
float a = ;
float b = ;
myswap(a, b); //自動資料類型 推導的方式
myswap<float>(a, b); //顯示類型調用
cout<<"hello..."<<endl;
system("pause");
return ;
}
1-2 函數模闆可以做函數的參數
#include <iostream>
using namespace std;
template<typename T, typename T2>
void sortArray(T *a, T2 num)
{
T tmp ;
int i, j ;
for (i=; i<num; i++)
{
for (j=i+; j<num; j++)
{
if (a[i] < a[j])
{
tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
}
}
}
template<class T>
void pirntArray(T *a, int num)
{
int i = ;
for (i=; i<num; i++)
{
cout<<a[i]<<" ";
}
}
void main()
{
int num = ;
char a[] = "ddadeeettttt";
num = strlen(a);
printf("排序之前\n");
pirntArray<char>(a, num);
sortArray<char, int>(a, num); //顯示類型調用 模闆函數 <>
printf("排序之後\n");
pirntArray<char>(a, num);
cout<<"hello..."<<endl;
system("pause");
return ;
}
1-3 函數模闆遇上函數重載
函數模闆和普通函數差別結論:
函數模闆不允許自動類型轉化
普通函數能夠進行自動類型轉換
函數模闆和普通函數在一起,調用規則:
1 函數模闆可以像普通函數一樣被重載
2 C++編譯器優先考慮普通函數
3 如果函數模闆可以産生一個更好的比對,那麼選擇模闆
不妨看下面的案例分析一波:
#include <iostream>
using namespace std;
template <typename T>
void myswap(T &a, T &b)
{
T t;
t = a;
a = b;
b = t;
cout<<"myswap 模闆函數do"<<endl;
}
void myswap(char &a, int &b)
{
int t;
t = a;
a = b;
b = t;
cout<<"myswap 普通函數do"<<endl;
}
void main()
{
char cData = 'a';
int iData = ;
//myswap<int>(cData, iData); //結論 函數模闆不提供隐式的資料類型轉換 必須是嚴格的比對
myswap(cData, iData);
//myswap(iData, cData);
cout<<"hello..."<<endl;
system("pause");
return ;
}
1-4 函數模闆機制結論:
編譯器并不是把函數模闆處理成能夠處理任意類的函數
編譯器從函數模闆通過具體類型産生不同的函數
編譯器會對函數模闆進行兩次編譯
在聲明的地方對模闆代碼本身進行編譯;在調用的地方對參數替換後的代碼進行編譯。
2.1 可以這樣聲明和使用類模闆:
1) 先寫出一個實際的類。由于其語義明确,含義清楚,一般不會出錯。
2) 将此類中準備改變的類型名(如int要改變為float或char)改用一個自己指定的虛拟類型名.
3) 在類聲明前面加入一行,格式為:
如:
template <class numtype> //注意本行末尾無分号
class Compare
{…}; //類體
4) 用類模闆定義對象時用以下形式:
類模闆名<實際類型名> 對象名;
類模闆名<實際類型名> 對象名(實參表列);
如:
Compare<int> cmp;
Compare<int> cmp(,);
5)如果在類模闆外定義成員函數,應寫成類模闆形式:
template <class 虛拟類型參數>
函數類型 類模闆名<虛拟類型參數>::成員函數名(函數形參表列) {…}
2.2 關于類模闆的幾點說明:
1) 類模闆的類型參數可以有一個或多個,每個類型前面都必須加class,如:
template <class T1,class T2>
class someclass
{…};
在定義對象時分别代入實際的類型名,如:
someclass<int,double> obj;
2) 和使用類一樣,使用類模闆時要注意其作用域,隻能在其有效作用域内用它定義對象。
3) 模闆可以有層次,一個類模闆可以作為基類,派生出派生模闆類。
2.3 類模闆在項目開發中的應用
小結
模闆是C++類型參數化的多态工具。C++提供函數模闆和類模闆。
模闆定義以模闆說明開始。類屬參數必須在模闆定義中至少出現一次。
同一個類屬參數可以用于多個模闆。
類屬參數可用于函數的參數類型、傳回類型和聲明函數中的變量。
模闆由編譯器根據實際資料類型執行個體化,生成可執行代碼。執行個體化的函數。
模闆稱為模闆函數;執行個體化的類模闆稱為模闆類。
函數模闆可以用多種方式重載。
類模闆可以在類層次中使用 。