什麼是類模板
類似函數模板,淡化數據類型,使用通用數據類型的模板。對僅成員數據類型不同的類的抽象,比如,有兩個或多個類,其功能是相同的,僅僅是數據類型的不同,那就可以聲明爲類模板。
一般形式:template <typename 參數名1,typename 參數名2,...>
template<typename T>
class Test
{
Test(T t){}
T Get() {}
void Set(T val) {}
private:
T DateMember;//類屬(類型參數化)參數必須至少在類說明中出現一次
};
int main()
{
Test<int> a(10);//類模板一定要顯示調用
a.Set(20);
a.Get();
system("pause");
return 0;
}
- 類模板用於實現類所需數據的類型參數化
- 類模板在表示如數組、表、圖等數據結構顯得特別重要,這些數據結構的表示和算法不受所包含的元素類型的影響
- 和函數模板一樣都需要進行二次編譯(在聲明的地方對模板代碼本身進行編譯,在調用的地方對參數替換後在進行編譯)
- 函數模板可以自動類型推導,類模板不能自動類型推導
繼承中的類模板
子類從模板類繼承時,需要讓編譯器知道父類的數據類型具體是什麼。
怎麼理解上面的話:以爲在類初始化對象時需要分配內存空間大小,如果不顯示聲明,那麼這個類無法初始化(數據類型的本質:固定大小內存塊的別名)
類模板派生普通類
template<typename T>
class A
{
public:
A(T x)
{
t = x;
}
void Print()
{
cout << "t = " << t << endl;
}
protected:
T t;
};
class B:public A<int>
{
public:
B(int a, double b) :A<int>(a)//必須顯示聲明
{
y = b;
}
void Print()
{
A<int>::Print();//必須顯示聲明
cout << "y = " << y << endl;
}
private:
double y;
};
int main()
{
A<int> a(3);//必須顯示聲明
a.Print();
B b(8, 2.5);
b.Print();
system("pause");
return 0;
}
在定義B類時,A類已實例化成了int型的模板類(編譯時完成)。
類模板派生類模板
template<typename T>
class A
{
public:
A(T x)
{
t = x;
}
void Print()
{
cout << "t = " << t << endl;
}
protected:
T t;
};
template<typename T>
class B:public A<T>
{
public:
B(int a, double b) :A<T>(a)//必須顯示聲明
{
y = b;
}
void Print()
{
A<T>::Print();//必須顯示聲明
cout << "y = " << y << endl;
}
private:
T y;
};
int main()
{
A<int> a(3);//必須顯示聲明
a.Print();
B<T> b(8, 2.5);
b.Print();
system("pause");
return 0;
}
類模板的作用
是泛型編程的基礎,就是用獨立於任何特定類型的方式來編寫代碼,簡單的來說,類是對象的抽象,對象時具體的,而模板是類的抽象,用模板能定義出具體的類。
C++中多態分爲兩種:
動態:虛函數
靜態:函數重載,泛型編程
類模板中的static關鍵字
- 從類模板實例化的每個模板類有自己的類模板數據成員,該模板類的所有對象共享一個static數據成員
- 和非模板類的static數據成員一樣,模板類的static數據成員也應該在文件範圍定義和初始化
- 每個模板類有自己的類模板的static數據成員副本
#pragma warning(disable : 4996)
#include <iostream>
using namespace std;
template <typename T>
class A
{
public:
static T m_a;
};
template <typename T>
T A<T>::m_a = 0;
int main()
{
A<int> a1, a2, a3;
a1.m_a = 10;
a2.m_a++;
a3.m_a++;
cout << A<int>::m_a << endl;
A<char> a4, a5, a6;
a4.m_a = 'a';
a5.m_a++;
a6.m_a++;
cout << A<char>::m_a << endl;
system("pause");
return 0;
}