C++模板之——类模板详解及代码示例
引言
上一篇文章,我们聊了C++的函数模板,今天我们来聊聊类模板。
一、类模板
1.1 作用
建立一个通用类,类中的成员和数据类型可以不具体指定,使用一个虚拟的类型来代替。
语法:
template<typename T>
类声明或者定义
说明:
template —— 表明要创建类模板。
typename —— 表示一种数据类型,可以用 class 代替, T 就是具体的名称,通常为大写字母。
1.2 代码示例
#include <iostream>
#include <string>
using namespace std;
// 类模板
template<class nameType, class ageType>
class Person{
public:
Person(nameType name, ageType age){
this->m_name = name;
this->m_age = age;
}
nameType m_name;
ageType m_age;
};
int main(int argc, char* argv[])
{
Person<string, int> p1("panda", 20);
std::cout << "p1.name: " << p1.m_name << " p1.age: "<< p1.m_age<< std::endl;
return 0;
}
1.2 类模板与函数模板的区别
- 类模板没有自动类型的推到使用方法
- 类模板可以再模板参数列表中有默认参数类型
// 类模板
template<class nameType, class ageType = int> // ageType类型默认为int
class Person{
public:
Person(nameType name, ageType age){
this->m_name = name;
this->m_age = age;
}
nameType m_name;
ageType m_age;
};
int main(int argc, char* argv[])
{
Person<string, int> p1("panda", 20);
std::cout << "p1.name: " << p1.m_name << " p1.age: "<< p1.m_age<< std::endl;
// Person p("panda", 20); // 错误,不能自己推导数据类型
Person<string> p2("lwang", 20);
std::cout << "p2.name: " << p2.m_name << " p2.age: "<< p2.m_age<< std::endl;
return 0;
}
运行结果:
1.3 类模板中成员函数创建时机
- 普通类函数成员一开始就可以创建出来
- 类模板中的函数成员只有在调用的时候才创建
示例:
class Student{
public:
void showStudentInfo()
{
std::cout << "Student show." << std::endl;
}
};
class Teacher{
public:
void showTeacherInfo()
{
std::cout << "Teacher show." << std::endl;
}
};
template<class T>
class Person{
public:
T obj;
// 成员函数
void func1()
{
obj.showStudentInfo();
}
void func2()
{
obj.showTeacherInfo();
}
};
int main(int argc, char* argv[])
{
Person<Student> pStu;
pStu.func1();
// pStu.func2(); // 在确认Person的T的类型为Student后,编译器发现obj没有func2,编译报错
Person<Teacher> pTe;
// pTe.func1(); // 在确认Person的T的类型为Teacher后,编译器发现obj没有func1,编译报错
pTe.func2();
return 0;
}
运行结果:
1.4 类模板对象作为函数的参数如何传递
类模板实例化出的对象,作为函数的参数传递的方式有三种:
- 显示指定传入的类型
- 参数模板化
- 整个类模板化
template<class nameType, class ageType = int> // ageType类型默认为int
class Person{
public:
Person(nameType name, ageType age){
this->m_name = name;
this->m_age = age;
}
nameType m_name;
ageType m_age;
};
void showPerson1(Person<string> &p)
{
std::cout << "p.name: " << p.m_name << " p.age: "<< p.m_age<< std::endl;
}
template<class T1, class T2>
void showPerson2(Person<T1, T2>& p)
{
std::cout << "p.name: " << p.m_name << " p.age: "<< p.m_age<< std::endl;
// std::cout << "T1 type is: " << typeid(T1).name() << std::endl;
// std::cout << "T2 type is: " << typeid(T2).name() << std::endl;
}
template<class T>
void showPerson3(T& p)
{
std::cout << "p.name: " << p.m_name << " p.age: "<< p.m_age<< std::endl;
// std::cout << "T type is: " << typeid(T).name() << std::endl;
}
int main(int argc, char* argv[])
{
// 1. 显式指定参数类型
Person<string> p("panda", 20);
showPerson1(p);
Person<string, int> p1("lwang", 35);
// 2. 参数模板化
showPerson2(p1);
// 3. 整个类模板化
Person<string, int> p2("lyz", 18);
showPerson3(p2);
return 0;
}
运行结果: