类模板作用:
- 建立一个通用类,类中的成员 数据类型可以不具体指定,用一个虚拟的类型来代表。
语法:
template<typename T>
类 // 函数模板此处写函数,类模板,此处写类。
解释:
- template:声明创建模板
- typename:表明其后面的符号是一种数据类型,可以用class代替。
- T :通用的数据类型,名称可以替换,通常为大写字母。
普通类:成员属性确定。
// 普通类
class Person1
{
public:
Person1(string name, int age)
{
m_Name = name;
m_Age = age;
}
string m_Name;
int m_Age;
};
类模板:成员属性不确定。
// 类模板
template<typename NameType, typename AgeType>
class Person2
{
public:
Person2(NameType name, AgeType age)
{
m_Name = name;
m_Age = age;
}
NameType m_Name;
AgeType m_Age;
};
typename关键字可以换成class。
调用情况:
void test01()
{
Person2<string, int> p2("张三", 18);
cout << "姓名:" << p2.m_Name << ", 年龄:" << p2.m_Age << "。" << endl;
}
类模板没有自动类型推导的使用方式。编译器自己去推导类型,推到不出来。只能用显示指定类型方式调用。
类模板与函数模板的区别
- 类模板没有自动类型推导的使用方式。
- 类模板在模板参数列表中可以有默认参数。
默认参数:实现方式:
template<class NameType, class AgeType = int>
在调用时:
Person <string> p("猪八戒", 999); //类模板中的模板参数列表 可以指定默认参数
类模板可以使用默认参数,函数模板没有这种使用方式。
类模板中成员函数的创建时机
类模板中成员函数和普通类中成员函数创建时机是有区别的:
普通类中的成员函数一开始就可以创建
类模板中的成员函数在调用时才创建
有三个类:
class Person1
{
public:
void showPerson1()
{
cout << "Person1 show" << endl;
}
};
class Person2
{
public:
void showPerson2()
{
cout << "Person2 show" << endl;
}
};
template<class T>
class MyClass
{
public:
T obj;
//类模板中的成员函数,并不是一开始就创建的,而是在模板调用时再生成
void fun1() { obj.showPerson1(); }
void fun2() { obj.showPerson2(); }
};
在类模板MyClass中,有两个函数func1, func2,这两个函数,在编译时,没有任何问题,可以通过。
但是当我们调用时:
void test01()
{
MyClass<Person1> m;
m.fun1();
//m.fun2();//编译会出错,说明函数调用才会去创建成员函数
}
总结:类模板中的成员函数并不是一开始就创建的,在调用时才去创建