容器类应该包含对象,而迭代器类的对象标识容器中的位置
- Seq类: 精简指令集容器类,模仿纯Lisp中的列表(list)
技术状况
- 类似: 数组包含若干值,辅助值(整数/指针)标识数组中某个位置
|
|
a作为容器,i作为迭代器
容器可以使const类型的,需要两种迭代器:
- 只能对容器进行读操作,
T*
- 只能对容器进行读操作,
- 既能对容器进行读操作又能进行写操作,
const T*
- 既能对容器进行读操作又能进行写操作,
传统观点
Lisp最初定义的列表:
nil
: 没又元素的列表cons(a, b)
: 列表中,第一个元素为a, 其后的元素为列表b中元素car(s)
: s的第一个元素,s是至少有一个元素的列表cdr(s)
: s的第一个元素之外的其他所有元素,s至少有一个元素的列表null(s)
: 列表s没有元素则为真,否则为假使用C++的模板定义类
Seq<T>
Seq<T>()
: 创建并返回一个没有元素的列表Seq<T>(t, s)
: 创建并返回一个序列(第一个元素为t、其后元素都是序列s中的元素)s.hd()
: 返回s的第一个元素,s至少有一个元素s.tl()
: 创建并返回一个序列(包含s中除了第一个元素外的所有其他元素,s至少有一个元素)(bool)s
: s没有元素则返回false,否则返回true
|
|
- 避免复制Seq或者子序列,使Seq在合适的时候共享底层序列
- 给元素一个引用计数
|
|
技巧: 根据一个值或者一个已有的Seq创建一个新的Seq;之后两个Seq共享有s表示的尾链
- 正确递增引用计数
|
|
采用引用计数,每次创建、销毁或者赋值给一个Seq对象时都需要处理
需要拷贝构造函数、析构函数和赋值操作符
|
|
- 缺省(默认)构造函数
|
|
- 从一个指向T的引用和另一个Seq构造一个新的Seq
|
|
- 布尔转型操作符
|
|
- 复制(拷贝)构造函数
|
|
- hd操作返回第一个Seq_item中的值,序列为空时抛出异常
|
|
- 定义私有构造函数,实现tl
|
|
- 删除序列时,可以只删除共享尾链前的元素
- 增加函数管理引用计数和在适当的时候删除Seq_item元素
|
|
额外操作
Seq<T>(t, s)
: 显式声明类型T(未知类型)
|
|
- 增加操作便于C++程序员使用
operator*()
:hd()
同义函数
operator++()
: 简化赋值语句s = s.tl()
|
|
- 在列表头部放入新值
|
|
使用范例
......
更多增加
联接操作:
operator+=
,operator+
对相等性(不等性)的检验
- 增加length(长度)操作利于高效实现
|
|
- 在Seq对象中存储长度
|
|
构造函数、赋值操作符、加法操作符、联接操作符、insert和tl函数都将被更新
接受一个Seq_item的private构造函数
|
|
《C++沉思录(Cplusplus Thinking)》笔记