网页设计代码大全下载网站关键字优化软件
实现自己的迭代器
最近在写数据结构,使用类模板实现,碰到了一些问题,其中有一个就是遍历的问题,查阅资料最后实现了自己的迭代器,让我实现的数据结构能像STL一样进行for循环遍历。
类的构成
#include <stdexcept>
#include <iterator>
template <typename T>
class Queue
{
public:// 迭代器class iterator;class const_iterator;typedef std::reverse_iterator<iterator> reverse_iterator;typedef std::reverse_iterator<const_iterator> const_reverse_iterator;Queue() : _capacity(5), _size(0), _items(new T[_capacity]), _front(0), _rear(-1) {}~Queue();// 入队void enqueue(const T &item);// 出队T dequeue();// 查看队首元素T front() const;// 查看队尾元素T rear() const;// 获取队列元素数量unsigned int size() const;iterator begin() noexcept;iterator end() noexcept;const_iterator begin() const noexcept;const_iterator end() const noexcept;reverse_iterator rbegin() noexcept;reverse_iterator rend() noexcept;const_reverse_iterator rbegin() const noexcept;const_reverse_iterator rend() const noexcept;private:// 存储元素的数组T *_items;// 队列当前容量unsigned int _capacity;// 队列当前大小unsigned int _size;// 队首unsigned int _front;// 队尾unsigned int _rear;// 调整队列的大小void resize();// 判断队列是否为空bool empty() const;// 判断当前队列是否为满bool full() const;
};
可以看到,我声明了两个类iterator
和const_iterator
,这两个类就是需要我们自己定义的迭代器。
官方定义
template <class Category, class T, class Distance = ptrdiff_t,class Pointer = T*, class Reference = T&>struct iterator {typedef T value_type;typedef Distance difference_type;typedef Pointer pointer;typedef Reference reference;typedef Category iterator_category;};
对于官方定义的迭代器结构,有5个参数,在后续实现自己的迭代器使需要设置。
自定义迭代器的实现
iterator
template <typename T>
class Queue<T>::iterator
{
public:// 标准写法// 迭代器的类型using iterator_category = std::bidirectional_iterator_tag;// 数据类型using value_type = T;// 迭代器之间的逻辑距离using difference_type = std::ptrdiff_t;// 指针using pointer = T*;// 引用using reference = T&;// 构造函数iterator(pointer data = nullptr,unsigned int pos = 0,unsigned int capacity = 0,unsigned int start = 0,unsigned int size = 0): _data(data), _pos(pos), _capacity(capacity), _start(start), _size(size) {}// 实现运算符重载// 解引用reference operator*() const {return this->_data[(this->_start + this->_pos) % this->_capacity];}// 成员访问pointer operator->() const{return &(operator*());}// 前++运算符iterator& operator++(){++this->_pos;return *this;}// 后++运算符iterator operator++(int){iterator tmp = *this;++this->_pos;return tmp;}// 前--运算符iterator& operator--(){--this->_pos;return *this;}// 后--运算符iterator operator--(int){iterator tmp = *this;--this->_pos;return tmp;}// 比较运算符bool operator==(const iterator& other) const{return this->_pos == other._pos;}bool operator!=(const iterator& other) const{return !(*this == other);}private:pointer _data; // 指向队列数据数组的指针unsigned int _pos; // 当前逻辑位置unsigned int _capacity; // 队列容量unsigned int _start; // 队列实际起始位置unsigned int _size; // 队列当前元素数量
};
const_iterator
template <typename T>
class Queue<T>::const_iterator
{// 标准写法// 迭代器的类型using iterator_category = std::bidirectional_iterator_tag;// 数据类型using value_type = const T;// 迭代器之间的逻辑距离using difference_type = std::ptrdiff_t;// 指针using pointer = const T*;// 引用using reference = const T&;// 构造函数const_iterator(const pointer data = nullptr,unsigned int pos = 0,unsigned int capacity = 0,unsigned int start = 0,unsigned int size = 0): _data(data), _pos(pos), _capacity(capacity), _start(start), _size(size) {}// 实现运算符重载// 解引用reference operator*() const {return this->_data[(this->_start + this->_pos) % this->_capacity];}// 成员访问pointer operator->() const{return &(operator*());}// 前++运算符const_iterator& operator++(){++this->_pos;return *this;}// 后++运算符const_iterator operator++(int){const_iterator tmp = *this;++this->_pos;return tmp;}// 前--运算符const_iterator& operator--(){--this->_pos;return *this;}// 后--运算符const_iterator operator--(int){const_iterator tmp = *this;--this->_pos;return tmp;}// 比较运算符bool operator==(const const_iterator& other) const{return this->_pos == other._pos;}bool operator!=(const const_iterator& other) const{return !(*this == other);}private:pointer _data; // 指向队列数据数组的指针unsigned int _pos; // 当前逻辑位置unsigned int _capacity; // 队列容量unsigned int _start; // 队列实际起始位置unsigned int _size; // 队列当前元素数量
};
begin()和end()的实现
template <typename T>
typename Queue<T>::iterator Queue<T>::begin() noexcept
{return iterator(this->_items, 0, this->_capacity, this->_front, this->_size);
}template <typename T>
typename Queue<T>::iterator Queue<T>::end() noexcept
{return iterator(this->_items, this->_size, this->_capacity, this->_front, this->_size);
}template <typename T>
typename Queue<T>::const_iterator Queue<T>::begin() const noexcept
{return const_iterator(this->_items, 0, this->_capacity, this->_front, this->_size);
}template <typename T>
typename Queue<T>::const_iterator Queue<T>::end() const noexcept
{return const_iterator(this->_items, this->_size, this->_capacity, this->_front, this->_size);
}
rbegin()和rend()的实现
template <typename T>
typename Queue<T>::reverse_iterator Queue<T>::rbegin() noexcept
{return reverse_iterator(this->end());
}template <typename T>
typename Queue<T>::reverse_iterator Queue<T>::rend() noexcept
{return reverse_iterator(this->begin());
}template <typename T>
typename Queue<T>::const_reverse_iterator Queue<T>::rbegin() const noexcept
{return const_reverse_iterator(this->end());
}template <typename T>
typename Queue<T>::const_reverse_iterator Queue<T>::rend() const noexcept
{return const_reverse_iterator(this->begin());
}
其他代码自己就不放出来了,主要是为了说明自定义迭代器,可以参照我的代码实现自己的迭代器。
测试
void testQueue()
{Queue<int> que;que.enqueue(4);que.enqueue(2);que.enqueue(5);std::cout << que.rear() << std::endl;for(const auto& item : que){std::cout << item << " ";}std::cout << std::endl;for(auto it = que.rbegin(); it != que.rend(); ++it){std::cout << *it << " ";}std::cout << std::endl;
}int main() {testQueue();return 0;
}
输出的结果为:
5
4 2 5
5 2 4