类模板与继承
tip1:
注意,类模板可以作父类,但是当子类继承他的时候需要在子类中指定标明参数列表,否则会报错,如下图所是:
正确写法:
//父类模板类
template<class T1,class T2>
class base {
public:
T1 t1;
T2 t2;
};
//子类
class son :public base<int, string> {};
tip2:如果想要更灵活的在构建对象的时候确立类型的话,就把子类也设置为模板类,这样就能在构建子类对象的的时候为自己和父类指定类型。
#include<iostream>
using namespace std;
//父类模板类
template<class T1, class T2>
class base {
public:
T1 t1;
T2 t2;
};
//子类
template<class T1, class T2, class T3>
class son :public base<typename T2, typename T3> { //这里的typename不能换成class,下面会给出一张图来解释。
public:
T1 t1;
son() {
cout << typeid(T1).name() << endl;
cout << typeid(T2).name() << endl; //便于我们查看类型名的函数。
cout << typeid(T3).name() << endl;
}
};
void test01() {
son<int, string, char> s;
}
int main() {
test01();
}
knowledge tip: 子类对父类进行类型指定的时候只能用typename,不能用class,如下图所示
类模板成员函数的类外实现
我们已经知道了如何类内实现,现在我们要学习一下该怎么类外实现,其实差不多,就是在::作用域符前加一个单括号括起来的类型表就行。
语法:
template<模板参数表>
类型名 类名<模板参数标识符列表>::函数名(参数表)
#include<iostream>
#include<string>
using namespace std;
//父类模板类
template<class T1, class T2>
class base {
public:
T1 t1;
T2 t2;
base(T1 t1, T2 t2);
void func();
};
//构造函数的写法
template<class T1, class T2>
base<T1, T2>::base(T1 t1, T2 t2) { //和以前的不同就是作用域前面加上了<T1,T2>
cout << "i am base" << endl;
this->t1 = t1;
this->t2 = t2;
}
//成员函数的写法
//一定要先在前面加上一行声明模板的template<>
template<class T1, class T2>
void base<T1, T2>::func() {
cout << "i am func" << endl;
}
int main() {
base<int, string>b(100, "zz");
}
错误警示:类内声明函数的时候后面不要加{},加上了就会产生下面的错误。
补充:
如何用类模板建立一个对象,应按如下形式声明:
模板名<模板参数表>对象名1,...............对象名n;
(看看是不是和vector容器的声明语法特别像,实际上vector就是一个类模板,用vector创建的动态数组都是vector类模板对象。