类模板与模板类的区别及模板类的实现时机(含示例)
一、类模板和模板类的区别
1. 类模板
定义:是模板的通用定义,并非实际存在的类,通过通用类型参数(如T1、T2
)描述类的结构,类型参数需在实例化时替换为具体类型。
语法:template <class T1, class T2, ...> class 类名 { ... };
特点:仅为类的 “蓝图”,不对应具体类型,无法直接创建对象,需通过实例化生成可使用的类。
文档示例:
cpp
// 类模板:使用T1、T2作为通用类型参数,未指定具体类型
template <class T1, class T2>
class Data {
public:
T1 a; // 通用类型成员
T2 b; // 通用类型成员
// 其他成员函数声明...
};
2. 模板类
定义:是类模板实例化后的具体类,通过将类模板的通用类型参数替换为实际类型(如int、double
)生成,是实实在在的类。
实例化方式:类名<具体类型1, 具体类型2, ...> 对象名
特点:包含具体类型,可直接用于创建对象,有完整的类结构。
文档示例:
cpp
// 模板类:Data<int, double>是类模板Data的实例化结果
// 其中T1被替换为int,T2被替换为double
Data<int, double> zs; // zs是模板类Data<int, double>的对象
二、模板类的实现时机
模板类的实现发生在模板实例化阶段,即通过替换类模板的通用类型参数生成具体类的过程,具体分为以下方式:
1. 隐式实例化
定义:编译器在编译时,根据代码中创建对象时指定的具体类型,自动将类模板实例化为模板类。
特点:无需显式声明,由编译器自动完成。
文档示例:
cpp
// 创建对象时指定具体类型int和int,编译器自动实例化模板类Data<int, int>
Data<int, int> obj1;
// 创建对象时指定具体类型char和char,编译器自动实例化模板类Data<char, char>
Data<char, char> obj2;
2. 显式实例化
定义:由开发者明确指定类模板的具体类型,强制编译器生成对应的模板类(即使未直接创建对象)。
语法:template class 类名<具体类型1, 具体类型2, ...>;
文档衍生示例(符合文档语法规则):
cpp
// 显式实例化:强制编译器生成模板类Data<double, string>
template class Data<double, string>;
3. 模板具体化(特殊处理)
当模板类的默认实现不满足特定类型需求时,可通过全特化或偏特化对特定类型进行特殊处理,此时针对该类型的模板类按具体化后的定义实现。
(1)全特化(文档示例):
对类模板的所有类型参数指定具体类型,全特化的类内函数需在类内定义。
cpp
// 类模板(通用版本)
template <class T1, class T2>
class Stu {
private:
T1 a;
T2 b;
};
// 全特化:为T1=int、T2=double指定特殊实现
template <>
class Stu<int, double> { // 模板类Stu<int, double>的特殊版本
private:
int a; // T1固定为int
double b; // T2固定为double
// 特殊处理的成员函数(需在类内定义)
};
(2)偏特化(文档示例):
对类模板的部分类型参数指定具体类型,剩余参数仍为通用类型,偏特化的类内函数需在类内定义。
cpp
// 类模板(通用版本)
template <class T1, class T2>
class Stu {
private:
T1 a;
T2 b;
};
// 偏特化:T1固定为char*,T2仍为通用类型
template <class T2>
class Stu<char*, T2> { // 模板类Stu<char*, T2>的特殊版本
private:
char* a; // T1固定为char*
T2 b; // T2仍为通用类型
// 特殊处理的成员函数(需在类内定义)
};
总结
- 类模板是 “模板定义”(通用蓝图),模板类是 “实例化结果”(具体类);
- 模板类通过隐式实例化、显式实例化生成,特殊类型可通过全特化 / 偏特化定制实现