迭代器定义的守则

本文分析了hashtable迭代器的设计问题,提出通过继承基类和区分const_iterator与iterator,以及处理底层const,使迭代器使用更方便。作者还讨论了如何优化迭代器的构造函数和成员指针,以增强迭代器的灵活性。
摘要由CSDN通过智能技术生成

        最近在读hashtable的源码,感觉hashtable迭代器的定义方式令迭代器使用起来很别扭,而RBTree的迭代器和节点的定义是最精妙的。我根据二者的差别总结了一下令迭代器定义更好用的方法:

1.令迭代器都继承于一个基类

        这涉及到接受iterator和const_iterator的对称运算符的操作,这样设计的话可以令对称运算符左右两边都是基类的引用,二者就可以自由地比较。具体可以参数我这篇文章:迭代器const_iterator和iterator的实现方法与迭代器比较运算符的优化

2.不要让迭代器的成员有类的指针,而是细化到类成员的指针

        hashtable的迭代器是iterator和const_iterator两个模板,而不是像其他容器一样由一个模板生成。我在学习时想模仿其他容器将两个模板合并为一个模板,虽然可行,但是发现这样不太方便。究其原因,是因为迭代器接受了一个hashtable对象的指针。

//这是iterator的构造函数
__hashtable_iterator(node* n, hashtable* tab) : cur(n), ht(tab) {}

//这是const_iterator的构造函数
__hashtable_const_iterator(const node* n, const hashtable* tab)
: cur(n), ht(tab) {}

        上面代码中hashtable就是使用迭代器的类,cur表示指向当前节点的指针,因为hashtable迭代器移动跳过当前链时需要访问hashtable中的vector,所以还有一个指向hashtable的指针ht,因为这个vector是hashtable的私有成员,所以还要将这两个模板配置为友元。那么聚合的模板的构造函数只能设置成如下形式:

//__hashtable_iterator_base是基类,为了方便比较,将cur放到了这个类中,比较运算符进行指针的比较
__hashtable_iterator_base(node* x = nullptr) :cur(x) {}
//成员1
node* cur;

//iterator和const_iterator的迭代器模板
//cur只能设置成非底层const的,因为iterator需要改变cur指向对象的内容
//hashtable只能设置成const的,因为当const的hashtable创建const_iterator时,
//*this是底层const的,必须要将tab设置成底层const才能接受底层const的this指针
__hashtable_iterator(node* n, const hashtable* tab) :iterator_base(n), ht(tab) {}
//成员2
const hashtable* ht;

        cur设置成非const的,这跟其他容器一样,是否底层const由operator*和operator->返回类型决定。但是成员ht只能设置成const的,这样就导致iterator也无法改变ht中vector的值。其实目前这样的迭代器就已经满足使用了,因为iterator一般是针对节点,来改变节点的内容,不需要改变类型本身,hashtable中erase需要改变vector,但是erase是函数成员,能够越过iteartor的底层const直接操作vector,但是我还是想为迭代器提供更大的自由度。首先将迭代器中的const hashtable*替换为vector*,同时将hashtable的vector成员替换为vector*,这样对于const的hanshtable对象,其vector*仅是一个顶层const,顶层const在拷贝中是能够被忽略的,因此const对象也能调用接受vector*的迭代器构造函数。底层const不由成员是否有底层const来决定,而是由限定重载来完成底层const。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值