二、类模版
类的成员变量,成员函数,成员类型,以及基类中如果包含参数化的类型,那么该类就是一个类模板
1.定义:
template<typename 类型形参1,typename 类型形参2,...>
class 类模板名[:基类]{
成员变量
成员函数
成员类型
};
2.使用
类模板名<类型实参1,类型实参2,...> 对象;
类模板名<类型实参1,类型实参2,...> &引用 = 对象;
类模板名<类型实参1,类型实参2,...> *指针 = &对象;
|<————类/类型/作用域-———>|
类模板不能隐式推断,必须显示指明类型实参.
3.两步实例化
编译期 运行期
类模板 — 实例化 -> 类 — 实例化 -> 对象
编译器 处理器
参见: class.cpp
只有当调用成员函数的时候才 编译器才做类型检查
4.类型参数
类模板中,所有的成员函数(无论其是否使用类型参数)都是函数模板,都要延迟编译(即在编译器看到调用该函数时编译),因此,只有那些被调用的成员函数才会被实例化
某些类型虽然没有提供该类模板所需要的全部功能,但照样可以实例化该模板,只要不直接或间接调用那些依赖于未提供功能的成员函数即可
5.类模板的静态成员变量
非模板:
- 静态成员变量是类的一部分,一个类只有一份
- 普通成员变量是对象的一部分,每个对象都有一份
类模板的静态成员变量,既不是一个模板一份实例,也不是一个对象一份实例,而是在该类模板的每个实例化类中都有一份对立的实例,且为该实例化类所创建的每个对象所共享。
-----参见static.cpp
6.递归实例化
用一个类模板的实例化类型实例化该类模板自身
构建在空间上具有递归特征的复合结构,如:多维数组,二叉树等等
template<typename T> class Array{..};
template<typename T> class list{...};
template<typename T> class Tree{...};
Array<Array<int> > 二维数组
Array<List<int> > 链表数组
List<Array<int> > 数组链表
List<List<int> > 二维链表 ====>通过哈希值放姓名
Tree<List<Array<int> > > 数组链表树
参见:array.cpp
7.特化/特例化
当一个类模板的通用实现无法满足某些特殊类型的需要,或者虽然可以满足需要,但是性能不佳,这时可以编写针对该
特殊类型的特殊实现,这就叫类模板的特例化
(1)完全特化:针对全部类型参数所做的特化 =====>用的比较多
-
-
全类特化:用特定类型替换类型参数,把整个类模板重写一遍
-
成员特化:只重写类模板中部分与特定类型相关的成员函数 参见:spec.cpp
-
(2)局部特化(偏特化)
参见:part.cpp
MCB(memory control block)内存控制块
malloc分配的堆内存前面会多出12个字节,里面有三块内容,一个是分配的字节数,一个是在用状态,一个是指针指向一下个块.
free的时候,会访问这个MCB,因此不能对free的这个指针进行+-操作.
8.智能指针
(1)利用局部对象的析构函数销毁堆对象.
(2)通过操作符重载用智能指针来模拟平凡指针的用法
(3)通过类型参数泛型化所维护的堆对象
(4)通过转移语义避免浅拷贝和深拷贝的矛盾
(5)通过局部特化来区分单个对象和对象数组 ===>两种的释放方式不同
智能指针的实现 参见auto.cpp
C++2011一般不推荐使用auto_ptr,而是代之以smart_ptr ====>真正的只能指针
本文深入探讨了C++中的类模板概念,包括定义、使用、实例化过程、类型参数、静态成员变量、递归实例化、特化及智能指针等关键特性。详细解释了如何在编译期和运行期实例化类模板,以及类模板如何处理不同类型参数的实例化。

被折叠的 条评论
为什么被折叠?



