15.1 为什么要有类模板
- 类模板用于实现类所需数据的类型参数化
- 类模板在表示如数组、表、图等数据结构显得特别重要,这些数据结构的表示和算法不受所包含的元素类型的影响
15.2 单个类模板语法
注意:类模板的创建对象一定要显示调用(指明类型)
完整示例代码:
#include <iostream>
using namespace std;
template <typename T, typename U>
class Test
{
private:
T a;
U b;
public:
Test(T a, U b)
{
this->a = a;
this->b = b;
}
void show()
{
cout << a << " " << b << endl;
}
};
int main()
{
Test<int, char> t(1, 'a'); //类模板创建对象一定要显式调用
t.show();
return 0;
}
运行结果:
15.3 继承中的类模板语法
父类:
15.3.1 派生出普通类
模板类派生普通类 继承的同时对基类实例化
15.3.2 派生出模板类
模板类派生模板类 继承的同时不需要对Parent实例化,但是要声明虚拟类型
完整示例代码:
#include <iostream>
using namespace std;
template <typename T>
class Parent
{
protected:
T a;
public:
Parent(T a)
{
this->a = a;
}
void show()
{
cout << a << endl;
}
};
class Child : public Parent<int> //模板类派生普通类 继承的同时对基类实例化
{
public:
Child(int a) : Parent(a)
{
}
void show()
{
cout << a << endl;
}
};
template <typename T, typename U>
class Child2 : public Parent<T> //模板类派生模板类 继承的同时不需要对Parent实例化
{
private:
U b;
public:
Child2(T a, U b) : Parent<T>(a)
{
this->b = b;
}
void show()
{
cout << this->a << " " << b << endl;
}
};
int main()
{
Child c1(1);
c1.show();
Child2<int, double> c2(1, 1.11);
c2.show();
return 0;
}
运行结果:
15.4 类模板相关说明
15.4.1 所有的类模板函数写在类的内部
这种方式最为省事,简单
15.4.2 所有的类模板函数写在类的外部,在同一个cpp中
类内只做了函数声明:
具体的实现实在类的外部:
完整示例代码:
#include <iostream>
using namespace std;
template <typename T>
class Test
{
private:
T a;
public:
Test(T a);
void show();
~Test();
};
template <typename T>
Test<T>::Test(T a) //Test<T>表示Test是模板类,不是普通类
{
this->a = a;
}
template <typename T>
void Test<T>::show()
{
cout << a << endl;
}
template <typename T>
Test<T>::~Test()
{
}
int main()
{
Test<int> t(1);
t.show();
return 0;
}
运行结果:
15.4.3 所有的类模板函数写在类的外部,在不同的.h和.cpp中
这里实现了一个数组的模板类:
array.h
arrary.hpp文件(注意:这里是.hpp文件)
main.cpp文件
15.5 类模板中的static关键字
- 从类模板实例化的每个模板类有自己的类模板数据成员,该模板类的所有对象共享一个static数据成员
- 和非模板类的static数据成员一样,模板类的static数据成员也应该在文件范围定义和初始化
- 每个模板类有自己的类模板的static数据成员副本
注意:静态成员变量要在类的外部进行初始化
完整示例代码:
#include <iostream>
using namespace std;
template <typename T>
class Test
{
private:
T a;
public:
static int count;
public:
Test(T a)
{
this->a = a;
count++;
}
};
template <typename T>
int Test<T>::count = 0; // 在类的外部进行初始化
int main()
{
Test<int> t1(1);
Test<int> t2(1);
Test<int> t3(1);
Test<int> t4(1);
Test<int> t5(1);
Test<char> t6('a');
Test<char> t7('a');
Test<char> t8('a');
cout << Test<int>::count << endl; // 5
cout << Test<char>::count << endl; // 3
return 0;
}