C++ STL迭代器,在链表中实现简简简化版

首先,迭代器是STL里的一大重点,它实现了对各种封装容器的遍历,保证了容器封闭的同时能够将其应用到STL中的算法里面。 其本质还是对容器数据成员的指针进行操作,并重载了一些操作符以实现简便操作。

纸上得来终觉浅,上代码。

  • 首先构造一个双向链表的结点Listnode
#include<iostream>
#include<vector>
using namespace std;

template <typename T1>
struct Listnode {
	Listnode* next_node;
	Listnode* pre_node;
	T1 val;
	Listnode() :next_node(nullptr) {};
	Listnode(Listnode& node) :next_node(node.next_node), pre_node(node.pre_node), val(node.val) {};
	Listnode(T1 _val, Listnode* nextnode=nullptr, Listnode* prenode = nullptr) :val(_val), next_node(nextnode), pre_node(prenode) {};
};
  • 其次构造一个链表的类list,其中包含了内部类list_iterator
template<typename T>
class list {
private:
	Listnode<T>* head, * tail;
	size_t size=0;
private:
	class list_iterator {
	private:
		Listnode<T>* ptr;
	public:
		list_iterator(Listnode<T>* _ptr = nullptr) :ptr(_ptr) {};
	};
public:
	typedef list_iterator iterator;
	list() {
		head = nullptr;
		tail = nullptr;
	}
	void push_back(const T t) {
		if (head == nullptr) {
			head = new Listnode<T>(t);
			tail = head;
		}
		else {
			tail->next_node = new Listnode<T>(t,nullptr,tail);
			tail = tail->next_node;
		}
		size++;
	}
	void pop_back() {
		if (head == nullptr) {
			cerr << "pop_back error, list is empty!" << endl;
		}
		else {
			Listnode<T>* temp =tail;
			tail = tail->pre_node;
			tail->next_node = nullptr;
			delete temp;
		}
		size--;
	}
	iterator begin const() {
		return iterator(head);
	}
	iterator end const() {
		return iterator();
	}
};

 类list当中,所有的成员变量都是private,包含的迭代器也是private,仅能通过几个成员函数进行访问,成员函数与STL容器基本保持一致的功能。

其中,迭代器类list_iterator,声明了一个私有变量指向单个结点,并定义一个构造函数以方便list获取首尾迭代器。

以上都比较明了,接下来重点说迭代器的内部成员函数实现。

class list_iterator {
	private:
		Listnode<T>* ptr;
	public:
		list_iterator(Listnode<T>* _ptr = nullptr) :ptr(_ptr) {};
		T& operator *() const {
			return ptr->val;
		}
        //前置++操作符
		list_iterator& operator++() {
			ptr = ptr->next_node;
			return *this;
		}
        //后置++操作符
		list_iterator operator++(int) {
			Listnode<T>* temp = ptr;
			ptr = ptr->next_node;
			return list_iterator(temp);
		}
		list_iterator& operator--() {
			ptr = ptr->pre_node;
			return *this;
		}
		list_iterator operator--(int) {
			Listnode<T>* temp = ptr;
			ptr = ptr->pre_node;
			return list_iterator(temp);
		}
		Listnode<T>* operator->() const {
			return ptr;
		}
		bool operator != (list_iterator t) const {
			return t.ptr != this->ptr;
		}
	};

其中,都是对各种操作符进行重载:

  • 操作符*,返回当前迭代器指向的结点的数据
  • 前置操作符++,使迭代器向后位移一个结点,直接返回位移后结点迭代器的引用
  • 后置操作符++,使迭代器向后位移一个结点,但返回位移前的结点迭代器。为了区分前置与后置的操作符,语法规定后置操作符需要写入int加以区分。而为什么返回不是引用?因为返回的是一个局部变量
  • 前置操作符--后置操作符--同理
  • 操作符->,为了能够直接由迭代器访问容器的内部数据成员,因此返回迭代器对应结点的指针
  • 关系操作符!===,对比两个迭代器是否指向同一个结点,返回bool类型

以上的操作,便能够完成使用迭代器对list内部成员的访问,无需了解list的内部构造。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值