欢迎光临
我们一直在努力

C++STL--list底层实现,迭代器分类,模拟list的迭代器封装、实现

在这里插入图片描述

博主名称:deM0one

⭐️C++专栏:
C++

文章目录

  • C++ STL list 容器底层原理:从零实现一个类 STL 的 list
    • 一、引言
    • 二、迭代器类型与性能特性
      • 2.1 迭代器类型
      • 2.2 性能特点
      • 2.3 支持双向迭代器的容器
    • 三、vector 的成员类型详解
    • 四、迭代器分类体系
    • 五、list 的内部结构设计
      • 5.1 循环双向链表 + 哨兵节点
      • 5.2 push_back 实现
    • 六、迭代器的封装与实现
      • 6.1 普通人的写法(不封装迭代器)
      • 6.2 仿 STL 的迭代器封装
    • 七、总结
    • 附录:参考资料

C++ STL list 容器底层原理:从零实现一个类 STL 的 list

一、引言

  • C++ STL(Standard Template Library)是 C++ 标准库的核心组件
  • list 作为双向链表容器,与 vector 等顺序容器有本质区别
  • 本文将从迭代器类型、内部结构、关键操作实现、迭代器封装四个维度,深度解析 list 的工作原理

二、迭代器类型与性能特性

2.1 迭代器类型

类型说明
iterator 普通迭代器,支持读写
reverse_iterator 反向迭代器,从尾部向前遍历
const_iterator 常量迭代器,只读访问
const_reverse_iterator 常量反向迭代器

2.2 性能特点

  • 支持双向遍历:可通过 ++ 和 — 操作前后移动
  • 不支持随机访问:无 operator[],不能通过下标直接访问元素
  • 时间复杂度:
    • 插入/删除:O(1)(已知位置)
    • 查找:O(n)

2.3 支持双向迭代器的容器

  • list、map、multimap
  • set、multiset
  • vector、string、deque(这些支持随机访问迭代器)

注意:STL 从 C++98 起就支持上述迭代器类型。


三、vector 的成员类型详解

以 std::vector<T, Alloc> 为例,其成员类型定义如下:

成员类型定义
value_type 模板第一个参数 T
allocator_type 模板第二个参数 Alloc
reference allocator_type::reference
const_reference allocator_type::const_reference
pointer allocator_type::pointer
const_pointer allocator_type::const_pointer
iterator 指向 value_type 的随机访问迭代器
const_iterator 指向 const value_type 的随机访问迭代器
reverse_iterator reverse<iterator>
size_type 无符号整数类型

关键点:vector 的迭代器是随机访问迭代器,而 list 的迭代器仅为双向迭代器。


四、迭代器分类体系

Input ← Output ← Forward ← Bidirectional ← Random Access

迭代器类型能力说明
Input Iterator 只读、单向、只能前进一次
Forward Iterator 可读写、可多次遍历同一元素
Bidirectional Iterator 可前可后移动(list、map 使用)
Random Access Iterator 支持任意位置跳跃(vector、deque 使用)

五、list 的内部结构设计

5.1 循环双向链表 + 哨兵节点

list 内部采用循环双向链表结构,并设置一个**哨兵节点(sentinel)**作为头节点。

protected:
link_type node; // 哨兵节点指针

public:
list() { empty_initialize(); }

void empty_initialize() {
node = get_node(); // 分配哨兵节点
node->next = node; // 自循环
node->prev = node;
}

设计意义:哨兵节点简化了边界处理,使得空链表和非空链表的处理逻辑保持一致。

5.2 push_back 实现

void push_back(const T& x) {
Node* newnode = new Node(x);
Node* tail = _head->prev; // 当前尾节点
tail->next = newnode; // 原尾部指向新节点
newnode->prev = tail; // 新节点指回原尾部
newnode->next = _head; // 新节点指向哨兵
_head->prev = newnode; // 哨兵指回新节点
}

插入过程图示:

tail newnode
↓ ↓
[head] ←── 1 ←── 2 ←── 3 ←── 4
↑ ↑
head newnode

  • 在链表尾部插入新节点 newnode
  • 更新原尾节点 tail 的 next 指向新节点
  • 新节点的 prev 指回 tail
  • 新节点的 next 指向 head
  • head 的 prev 指向新节点 → 形成闭环

六、迭代器的封装与实现

6.1 普通人的写法(不封装迭代器)

typedef list_iterator<T> iterator;

iterator begin() {
iterator it(_head->next);
return iterator(_head->next);
}

iterator end() {
return _head; // 返回哨兵节点
}

问题:直接暴露底层节点指针,缺乏封装,不符合 STL 规范。

6.2 仿 STL 的迭代器封装

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& s) {
return _node != s._node;
}
};

迭代器遍历图示:

pos
↓
[head] ←── 1 ←── 2 ←── 3 ←── 4
↑
head

  • 使用迭代器封装底层节点指针
  • 提供 operator*、operator++、operator!= 等基本操作
  • 符合 STL 迭代器协议,便于与泛型算法(如 sort、find)配合使用

七、总结

本文系统梳理了 C++ STL list 容器的核心设计:

  • 迭代器类型:list 使用双向迭代器,不支持随机访问
  • 内部结构:循环双向链表 + 哨兵节点,简化边界处理
  • 关键操作:empty_initialize 初始化哨兵,push_back 实现尾部插入
  • 迭代器封装:通过封装节点指针,提供符合 STL 规范的迭代器接口
  • 掌握这些原理,有助于深入理解 STL 设计思想,并为手写简易版容器打下坚实基础。


    附录:参考资料

    • 《C++ Primer》第 10 章:泛型算法与容器
    • SGI STL 源码剖析
    • cppreference.com:std::list

    任何的批评和建议欢迎指出,我们共同进步!

    赞(0)
    未经允许不得转载:171主机测评 » C++STL--list底层实现,迭代器分类,模拟list的迭代器封装、实现
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址