模板分爲函數和類模板
函數模板
建立一個函數類型和形參個數不具體指定的通用函數,以一個虛擬類型的形式存在,該類型即爲模板函數;
函數調用時系統根據實參類型來取代模板中的虛擬類型,實現不同函數功能;
這是系統指“編譯器”?源碼中函數模板怎麼處理確定形參個數問題,不能是指定所有不同形參類型,這裏的虛擬類型怎麼實現的?–C++程序設計所考慮的問題,先不深究。
C++編譯器根據函數模板生成不同函數(彙編源碼裏)
template <typename T>
函數模板和普通函數在一起調用規則
當函數模板和普通函數都符合調用規則時,優先調用普通函數;
若顯示使用函數模板,則使用<>類型列表;
若函數模板能夠產生更好的效果,則使用函數模板;
空模板的實參列表的語法限定編譯器只能通過模板匹配;
重載:?包括哪些:運算符重載(函數重載),類重載?
調用普通函數可以隱式類型轉換;
區別:
函數模板不允許變量類型自動轉化,而普通函數可****以;
類模板
定義類模板
template <class T>
class 類名{
.....
};
看個例子
//告訴C++編譯器開始使用泛型編程
//template <typename T>
template <class T>
class A{
public:
A(T t){
this->t = t;
}
T & getT(){
return t;
}
protected:
T t;
private:
};
void main(){
//告訴類模板數據類型便於分配空間
A<int> a(100);
}
模板繼承
在模板類A基礎上派生B類時,需要先告訴派生B的基類A的數據類型,
class B :public A<int>
C++中構造函數形式?
例子
#include <iostream>
using namespace std;
template <class T>
class Num_class{
//友元函數
friend Num_class Mysub(Num_class &c1, Num_class &c2){
Num_class tmp(c1.a-c2.a,c1.b-c2.b);
cout<<"c1.a-c2.a:"<<tmp.a<<":"<<tmp.b<<endl;
return tmp;
}
public:
//賦值構造函數
//構造函數聲明必須在類中,實現可類外;
//Num_class()
Num_class(T a, T b){
//this指針?
this->a = a;
this->b = b;
}
//*號運算符重載
Num_class operator*(Num_class &c2){
Num_class tmp(a*c2.a,b*c2.b);
cout<<"tmp.a: "<<tmp.a<<" tmp.b:"<<tmp.b<<endl;
return tmp;
}
//析構函數
//輸出函數
print_(){
//cout<<"a:"<<a<<end;
}
protected:
private:
//私有變量
T a;
T b;
};
int main(){
//模板類具體化,編譯器分配內存
Num_class<int> c1(1,3);
Num_class<int> c2(2,4);
// 運算符重載
Num_class<int> c3 = c1*c2;
//Error:私有成員變量在類外不能被訪問
//cout<<c3.a<<c3.b<<endl;
//友元函數
Mysub(c1,c2);
return 0;
}
類模板中static關鍵字
從類模板實例化的類模板有自己的數據成員,該模板類的所有對象共享一個static數據成員;
和非模板類的static數據成員一樣,模板類的static數據成員也應該在文件範圍定義和初始化;
每個模板類有自己的類模板的static數據成員副本;