【C++】深入理解list迭代器的设计与实现

发布于:2025-03-23 ⋅ 阅读:(29) ⋅ 点赞:(0)

引言

在STL容器中,list作为经典的双向链表容器,其迭代器设计体现了C++模板编程的精髓。本文将深入探讨如何从零开始设计一个符合STL规范的list迭代器,揭示其背后的设计哲学和技术细节。

1、链表基础结构

template <class T>
struct list_node {
	T data_;
	list_node<T>* next_;
	list_node<T>* prev_;
	list_node(const T& data = T()) 
		: data_(data), next_(nullptr), prev_(nullptr) { }
};

每一个节点包含前驱指针、后继指针和数据元素,构成双向链表的基础单元。

链表基础结构

2、链表迭代器的封装

list不像vector那样是一段连续的空间,方便通过直接通过+-来计算地址位置,因此不能采用原生指针进行typedef,需要将节点类型进行封装,通过运算符重载来达到移动“迭代器指针”

2.1 初步封装迭代器类

template <class T>
struct __list_iterator {
	typedef list_node<T> node;
	typedef __list_iterator<T> self;
	node* node_; // 成员变量,为一个节点的指针
	__list_iterator(node* node)
		: node_(node) { }

	// 解引用操作符重载
	T& operator*() {
		return node_->data_;
	}

	// 后置++操作符重载,完成迭代器的移动
	self& operator++() {
		node_ = node_->next_; // 移动到下一个节点
		return *this;
	}

	// !=操作符重载
	bool operator!=(const self& other) {
		return node_ != other.node_;
	}
};

2.2 引入const迭代器

如上述代码,若实现const迭代器,本能的反映是再封装一个迭代器类,但这个类与普通迭代器实现是没有区别的,只是在返回参数上有所改变。而再封装一个类导致了代码的冗余,我们是否可以只封装一个迭代器类,实现const和非const功能呢?

2.2.1 参考STL源代码

template<class T, class Ref, class Ptr>
struct __list_iterator {
  typedef __list_iterator<T, T&, T*>             iterator;
  typedef __list_iterator<T, const T&, const T*> const_iterator;
  typedef __list_iterator<T, Ref, Ptr>           self;
}
  • 从STL源代码中我们可以看到,list迭代器在设计中,使用了三个模板参数,分别是:
    • 数据类型T
    • 引用数据类型Ref
    • 指针数据类型Ptr

2.2.2 完善迭代器

template <class T, class Ref, class Ptr>
struct __list_iterator {
	typedef list_node<T> node;
	typedef __list_iterator<T, Ref, Ptr> self;
	node* node_; // 成员变量,为一个节点的指针
	__list_iterator(node* node)
		: node_(node) { }

	// 解引用操作符重载
	Ref operator*() {
		return node_->data_;
	}

	// 后置++操作符重载,完成迭代器的移动
	self& operator++() {
		node_ = node_->next_; // 移动到下一个节点
		return *this;
	}

	// !=操作符重载
	bool operator!=(const self& other) {
		return node_ != other.node_;
	}

	// ->操作符重载
	Ptr operator->() {
		return &(node_->data_);
	}
};

// typedef迭代器类
typedef __list_iterator<T, T&, T*> iterator;
typedef __list_iterator<T, const T&, const T*> const_iterator;

迭代器的封装

3、迭代器实现机制

操作类型 失效情况
插入操作 不影响现有迭代器
删除操作 被删除元素的迭代器立即失效
合并/转移操作 被转移元素的迭代器失效

结语

list迭代器设计体现了C++模板元编程的强大能力,通过精巧的类型系统设计和操作符重载,使得链表容器能够无缝接入STL算法体系。理解其实现原理不仅有助于深入掌握STL工作机制,更能提升我们对迭代器设计模式的认识。