C++迭代器iterator详解

知识的学习在于点滴记录,坚持不懈;知识的学习要有深度和广度,不能只流于表面,坐井观天;知识要善于总结,不仅能够理解,更知道如何表达!

迭代器概念

最近有人春招面试互联网大厂被问到这样一个问题:迭代器有什么用处?泛型算法的参数为什么接收的都是迭代器?

迭代器iterator是C++ STL的组件之一,作用是用来遍历容器,而且是通用的遍历容器元素的方式,无论容器是基于什么数据结构实现的,尽管不同的数据结构,遍历元素的方式不一样,但是用迭代器遍历不同容器的代码是完全一样的。经典的迭代器遍历容器的代码如下:

vector<int>::iterator it = vec.begin();
for (; it != vec.end(); ++it)
{
   
	cout << *it << " ";
}
cout << endl;
unordered_set<int>::iterator it = us.begin();
for (; it != us.end(); ++it)
{
   
	cout << *it << " ";
}
cout << endl;

实际上,C++11新标准的foreach语句,对于容器的遍历就是通过迭代器iterator实现的,如果容器没有实现iterator迭代器,那么foreach语句也无法遍历容器,上面vector容器的遍历代码可以简化为:

for (int val : vec) // 实际上是用迭代器遍历容器vec
{
   
	cout << val << " ";
}
cout << endl;

迭代器一般实现为容器的嵌套类型,在容器内部提供具体的实现。但是容器不同,底层元素遍历的方式也不同,那么为什么说迭代器遍历所有容器的方式是一样的呢?那是因为迭代器提供了常用的operator!=,operator++,operator*等运算符的重载函数,把迭代容器的细节全部隐藏在这些通用的运算符重载函数里面,因此用户侧表现出来的就是,迭代器遍历所有容器的方式都是一样的,其实底层都是不一样的风景^^

所以刚开始的那个问题就可以回答了,泛型算法是针对很多容器实现的通用算法,肯定需要一种统一的方式遍历容器的元素,只有迭代器才能做到!

iterator迭代器实现

这部分提供一个极简的vector容器实现,然后给它提供一个迭代器iterator的实现,看看容器迭代器的原理是什么,这里面容器的空间配置器直接使用C++标准库的allocator默认实现。

下面是极简vector容器以及迭代器的代码实现:

#include <iostream>

// 简单的vector容器实现,主要查看其嵌套类iterator迭代器的实现
template<typename T, 
	typename Alloc = std::allocator<T>>
class MyVector
{
   
public:
	MyVector(const Alloc &alloc = Alloc())
		:_allocator(alloc)
	{
   
		_first._ptr = _last._ptr = _end._ptr = nullptr;
	}

	template<typename T>
	void push_back(T &&val)
	{
   
		if (full())
			resize();
		_allocator.construct(_last._ptr, std::forward<T>(val));
		_last._ptr++;
	}

	void pop_back()
	{
   
		if (empty())
			return;
		_last._ptr--;
		_allocator.destroy(_last._ptr);
	}

	bool full()const {
    return _last._ptr == _end._ptr; }
	bool empty()const {
    return _first._ptr == _last._ptr; }

	// 容器迭代器的实现
	class iterator
	{
   
	public:
		friend class MyVector;
		iterator(T *ptr = nullptr)
			:_ptr(ptr) {
   }
		void operator++() {
    ++_ptr; }
		bool operator!=(const iterator &it) {
    return _ptr != it._ptr; }
		T& operator*() {
    return *_ptr; }
		T* operator->() {
    return _ptr; }
	private:
		T *_ptr;
	};
	// 容器的begin方法返回首元素迭代器
	iterator begin() {
    return iterator(_first._ptr); }
	// 容器的end方法返回末尾元素后继位置的迭代器
	iterator end() {
    return iterator(_last._ptr); }
private:
	iterator _first; // 指向数组其实地址
	iterator _last;  // 指向最后一个有效元素的后继位置
	iterator _end;   // 指向数据空间末尾元素的后继位置
	Alloc _allocator;// 容器底层的空间配置器

	// 容器的扩容函数
	void resize()
	{
   
		if (_first._ptr == nullptr)
		{
   
			_first._ptr = _allocator.allocate(1);
			_last._ptr = _first._ptr;
			_end._ptr = _first._ptr + 1;
		}
		else
		{
   
			int size = _last._ptr - _first._ptr;
			T *ptmp = _allocator.allocate(2 * size);
			for (int i = 0; i < size; ++i)
			{
   
				_allocator.construct(ptmp+i, _first._ptr[i]);
				_allocator.destroy(_first._ptr + i);
			}
			_allocator.deallocate(_first._ptr, size);
			_first._ptr = ptmp;
			_last._ptr = _first._ptr + size
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值