如何设计C++容器,能够包含类型不同而彼此相关的对象
如何将继承自同一父类的属于不同子类的对象装入同一个容器(如vector)之中?
(将容器和继承运用在一起)
- 代理 (surrogate) 允许将整个派生层次压缩在一个对象类型中
surrogate是handle(句柄)类中最简单的一种
一个表示不同交通工具的类派生层次
|
|
一个容器
|
|
- Vehicle是虚基类,不能实例化
- 子类对象转化为父类对象会丢失父类中没有的成员
- parking_lot是Vehicle的集合而不是所有继承自Vehicle的对象的集合
间接层 indirection
- 存储指针替代存储对象本身:
|
|
x是局部变量,释放之后parking_pot指向未知
存储副本的指针而非原对象的指针:
|
|
- 带来动态内存管理的负担
- 必须知道要放入parking_lot中的对象的静态类型
|
|
虚复制函数
- 在Vehicle中增加合适的纯虚函数来复制编译时类型未知的对象:
|
|
在Vehicle的所有派生类中添加成员函数copy,若vp指向Vehicle不确定的子类的对象,vp->copy()返回指向该对象新建副本的指针
例如:
|
|
定义代理类
- 用类表示概念
- 避免显示处理内存分配且能保持父类在运行时绑定的属性
定义一个行为与Vehicle对象相似而又潜在地表示所有继承自Vehicle对象的东西
- 代理 (surrogate)
|
|
- 空代理(empty surrogate)的行为类似于空指针
|
|
每次对copy的调用都是一个虚拟调用。类Vehicle的对象并不存在
赋值构造函数和赋值操作符中v.vp非零的检测是必需的
赋值操作符确保没有将代理赋值给自身
总结
- 最开始的parking_pot容器可设计为:
|
|
将继承和容器共用需要处理两个问题:
- 控制内存分配
- 把不同类型的对象放进同一个容器中
采用基础C++技术,在现有的继承层次上加上一层抽象,合适地解决了这些问题
《C++沉思录(Cplusplus Thinking)》笔记