类模板语法

类模板作用:

  • 建立一个通用类,类中的成员 数据类型可以不具体制定,用一个虚拟的类型来代表。

语法:

  1. template<typename T>

解释:
template — 声明创建模板
typename — 表面其后面的符号是一种数据类型,可以用class代替
T — 通用的数据类型,名称可以替换,通常为大写字母

  1. template<class NameType, class AgeType>
  2. class Person {
  3. public:
  4. Person(NameType name,AgeType age) {
  5. this->m_Age = age;
  6. this->m_Name = name;
  7. };
  8. void ShowPerson() {
  9. cout << "name: " << this->m_Name << " age: " << this->m_Age << endl;
  10. }
  11. NameType m_Name;
  12. AgeType m_Age;
  13. };
  14. void example() {
  15. Person<string, int> p1("Tom", 18);
  16. //尖括号的内容是模板参数列表
  17. p1.ShowPerson();
  18. }

类模板和函数模板的区别

  1. 类模板没有自动类型推导的使用方式
  2. 类模板在模板的参数列表中可以有默认参数。

    1. template <class NameType,class AgeType = int>
    2. class Person {
    3. public:
    4. Person(NameType name,AgeType age) {
    5. this->m_age = age;
    6. this->m_name = name;
    7. }
    8. void showPerson() {
    9. cout << "name: " << this->m_name << " age:" << this->m_age << endl;
    10. }
    11. NameType m_name;
    12. AgeType m_age;
    13. };
    14. void example() {
    15. Person<string, int> p("Tom", 100);//因为类模板不能自动类型推导,只能用显示数据类型
    16. p.showPerson();
    17. //We could have a default type here, so we don't have to point one
    18. Person <string> p2("Jack", 10);
    19. }

    只能使用显示数据类型
    可以使用参数

    类模板中的成员函数创建时机

    二者创建的时机有区别。

  3. 普通类的成员函数一开始就可以创建

  4. 但是类模板的成员函数在调用的时候才创建。

    1. class Person1
    2. {
    3. public:
    4. void showPerson1()
    5. {
    6. cout << "Person1 show" << endl;
    7. }
    8. };
    9. class Person2
    10. {
    11. public:
    12. void showPerson2()
    13. {
    14. cout << "Person2 show" << endl;
    15. }
    16. };
    17. template<class T>
    18. class MyClass
    19. {
    20. public:
    21. T obj;
    22. //类模板中的成员函数,并不是一开始就创建的,而是在模板调用时再生成
    23. void fun1() { obj.showPerson1(); }
    24. void fun2() { obj.showPerson2(); }
    25. };
    26. void test01()
    27. {
    28. MyClass<Person1> m;
    29. m.fun1();
    30. //m.fun2();//编译会出错,说明函数调用才会去创建成员函数
    31. }
    32. int main() {
    33. test01();
    34. system("pause");
    35. return 0;
    36. }

    上述代码在不进行实例化的时候,模板类不会被创建,所以不存在Myclass这个类,编译正常通过,如果将其实例化,则无法编译通过。

    类模板对象做函数参数

  5. 制定传入的类型 —直接显示对象的数据类型

  6. 参数模板化 —将对象中的参数变为模板进行传递
  7. 整个类模板化 —将这个对象类型 模板化进行传递 ```cpp

template class Person { public: Person(T1 name,T2 age) { this->m_age = age; this->m_name = name; } void showPerson() { cout << “name= “ << m_name << “ age= “ << m_age << endl; } T1 m_name; T2 m_age; }; //指定一个直接对象模板,制定传入类型,最常用,最稳定,可读性最高 void printPerson1(Person&p) { p.showPerson(); } //参数模板化,更加通用 template void printPerson2(Person&p) { p.showPerson(); cout << “T1的类型是” << typeid(T1).name() << endl; cout << “T2的类型是” << typeid(T2).name() << endl; } //整个类模板化,让编译器自动完成,集成度高,但是不稳定。 template void printPerson3(T &p) { p.showPerson(); cout << “T的数据类型是:” << typeid(T).name() << endl; } void example() { Person p1(“张三”, 18); printPerson1(p1); Person p2(“李四”, 20); printPerson2(p2); Personp3(“王五”, 25); printPerson3(p3); }

  1. 打印结果是:
  2. ```cpp
  3. name= 张三 age= 18
  4. name= 李四 age= 20
  5. T1的类型是class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
  6. T2的类型是int
  7. name= 王五 age= 25
  8. T的数据类型是:class Person<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,int>