C++自定义迭代器
实现自己的迭代器
最近在写数据结构,使用类模板实现,碰到了一些问题,其中有一个就是遍历的问题,查阅资料最后实现了自己的迭代器,让我实现的数据结构能像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