news 2026/6/15 11:51:23

C++ STL list容器深度解析与模拟实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++ STL list容器深度解析与模拟实现

📚 一、list容器介绍

1.1 基本概念

list是C++标准模板库(STL)中的一个序列容器,底层实现为带头节点的双向循环链表。这种结构使得list在任意位置插入和删除元素都具有很高的效率。

1.2 核心特性

  • 双向访问:可以从前后两个方向遍历

  • 动态内存:每个元素独立分配内存(节点)

  • 迭代器类型:双向迭代器(支持++和--操作)

  • 内存不连续:元素在内存中不是连续存储的

🔧 二、list的基本使用

2.1 构造函数

cpp

#include <list> #include <iostream> void test_construction() { // 1. 默认构造 - 空list std::list<int> list1; // 2. 构造包含n个相同元素的list std::list<int> list2(5, 100); // 5个100 // 3. 范围构造 int arr[] = {1, 2, 3, 4, 5}; std::list<int> list3(arr, arr + 5); // 4. 拷贝构造 std::list<int> list4(list3); // 5. 初始化列表构造(C++11) std::list<int> list5 = {1, 2, 3, 4, 5}; }

2.2 迭代器使用

cpp

void test_iterator() { std::list<int> lst = {1, 2, 3, 4, 5}; // 正向迭代器 std::cout << "正向遍历: "; for (auto it = lst.begin(); it != lst.end(); ++it) { std::cout << *it << " "; } std::cout << std::endl; // 反向迭代器 std::cout << "反向遍历: "; for (auto rit = lst.rbegin(); rit != lst.rend(); ++rit) { std::cout << *rit << " "; } std::cout << std::endl; // C++11范围for循环 std::cout << "范围for遍历: "; for (int val : lst) { std::cout << val << " "; } std::cout << std::endl; }

2.3 容量操作

cpp

void test_capacity() { std::list<int> lst = {1, 2, 3}; std::cout << "是否为空: " << lst.empty() << std::endl; std::cout << "元素个数: " << lst.size() << std::endl; // list没有capacity()方法,因为链表不需要预分配空间 }

2.4 元素访问

cpp

void test_element_access() { std::list<int> lst = {1, 2, 3, 4, 5}; if (!lst.empty()) { std::cout << "第一个元素: " << lst.front() << std::endl; std::cout << "最后一个元素: " << lst.back() << std::endl; } // list不支持随机访问,所以没有operator[]和at()方法 // 要访问第n个元素,需要遍历 }

2.5 修改操作

cpp

void test_modifiers() { std::list<int> lst; // 头部操作 lst.push_front(10); // 头部插入 lst.pop_front(); // 头部删除 // 尾部操作 lst.push_back(20); // 尾部插入 lst.pop_back(); // 尾部删除 // 中间插入 auto it = lst.begin(); ++it; // 移动到第二个位置 lst.insert(it, 30); // 在第二个位置插入30 // 删除 it = lst.begin(); lst.erase(it); // 删除第一个元素 // 清空 lst.clear(); }

⚠️ 三、迭代器失效问题

3.1 错误示例

cpp

// 错误写法:迭代器失效 void wrong_example() { std::list<int> lst = {1, 2, 3, 4, 5}; auto it = lst.begin(); while (it != lst.end()) { lst.erase(it); // 错误!删除后it失效 ++it; // 使用失效的迭代器,未定义行为 } }

3.2 正确写法

cpp

// 正确写法1:使用返回值更新迭代器 void correct_example1() { std::list<int> lst = {1, 2, 3, 4, 5}; auto it = lst.begin(); while (it != lst.end()) { it = lst.erase(it); // erase返回下一个有效迭代器 } } // 正确写法2:后置递增 void correct_example2() { std::list<int> lst = {1, 2, 3, 4, 5}; auto it = lst.begin(); while (it != lst.end()) { lst.erase(it++); // 先传递it,然后递增 } }

注意:对于list,只有指向被删除元素的迭代器会失效,其他迭代器不受影响。

🔨 四、list的模拟实现

4.1 节点结构

cpp

template<class T> struct ListNode { ListNode<T>* _prev; ListNode<T>* _next; T _data; ListNode(const T& val = T()) : _prev(nullptr) , _next(nullptr) , _data(val) {} };

4.2 list类框架

cpp

template<class T> class List { private: ListNode<T>* _head; // 头节点(哨兵节点) public: // 迭代器类 class iterator { private: ListNode<T>* _node; public: iterator(ListNode<T>* node = nullptr) : _node(node) {} // 前置++ iterator& operator++() { _node = _node->_next; return *this; } // 后置++ iterator operator++(int) { iterator temp(*this); _node = _node->_next; return temp; } // 解引用 T& operator*() { return _node->_data; } // 箭头运算符 T* operator->() { return &_node->_data; } // 比较运算符 bool operator!=(const iterator& it) { return _node != it._node; } bool operator==(const iterator& it) { return _node == it._node; } }; // 构造函数 List() { _head = new ListNode<T>(); _head->_prev = _head; _head->_next = _head; } // 析构函数 ~List() { clear(); delete _head; _head = nullptr; } iterator begin() { return iterator(_head->_next); } iterator end() { return iterator(_head); } // 插入、删除等其他方法... };

4.3 反向迭代器实现

cpp

template<class Iterator> class ReverseIterator { private: Iterator _it; public: ReverseIterator(Iterator it) : _it(it) {} // 前置++ ReverseIterator& operator++() { --_it; return *this; } // 后置++ ReverseIterator operator++(int) { ReverseIterator temp(*this); --_it; return temp; } // 解引用(注意反向迭代器的特殊处理) typename Iterator::reference operator*() { Iterator temp = _it; --temp; return *temp; } // 其他必要操作... };

📊 五、list与vector对比

特性vectorlist
底层结构动态数组,连续内存双向链表,非连续内存
随机访问O(1)(支持)O(n)(不支持)
插入/删除尾部O(1),其他位置O(n)任意位置O(1)(已知位置)
内存使用连续,缓存友好,空间利用率高碎片化,缓存不友好,每个元素额外开销
迭代器类型随机访问迭代器双向迭代器
迭代器失效插入/删除可能导致全部迭代器失效只有被删除元素的迭代器失效
适用场景需要随机访问,尾部操作频繁频繁在任意位置插入/删除

🎯 六、选择指南

使用vector的场景:

  • 需要频繁随机访问元素

  • 元素数量变化不大,主要在尾部操作

  • 对缓存性能要求高

  • 需要与其他C函数或库交互(连续内存)

使用list的场景:

  • 频繁在中间位置插入/删除元素

  • 不需要随机访问,主要是顺序访问

  • 元素较大,移动成本高

  • 需要稳定的迭代器(不被插入操作影响)

💡 七、最佳实践

  1. 优先选择vector:除非有明确的理由,否则vector通常是更好的选择

  2. 考虑deque:如果需要头尾高效操作,考虑使用deque

  3. 使用算法库:结合STL算法(如sort、find等)使用

  4. 注意迭代器失效:特别是在循环中修改容器时

总结

list作为STL中的双向链表容器,在特定场景下具有不可替代的优势。理解其底层实现原理、迭代器机制以及与vector的区别,能够帮助我们在实际开发中做出更合理的选择。通过模拟实现list,我们能够更深入地理解STL容器的设计思想,提升C++编程能力。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/16 23:23:55

如何通过TensorRT提升推理服务的审计追踪能力?

如何通过TensorRT提升推理服务的审计追踪能力&#xff1f; 在金融风控系统中&#xff0c;一次模型误判可能导致数百万资金损失&#xff1b;在医疗影像诊断场景里&#xff0c;AI给出的结论需要经得起事后复核。这些高合规性领域对人工智能系统提出了一个尖锐的问题&#xff1a;我…

作者头像 李华
网站建设 2026/6/13 17:17:37

KeilC51和MDK同时安装实战:从零配置双环境完整指南

Keil C51 与 MDK-ARM 共存实战&#xff1a;一文搞定双开发环境配置 你有没有遇到过这样的场景&#xff1f; 手头要维护一个老旧的 8051 单片机项目&#xff0c;同时又要开发基于 STM32 的新设备。想用 Keil&#xff0c;却发现装了 C51 后再装 MDK 出现编译器混乱、工程打不开、…

作者头像 李华
网站建设 2026/5/15 16:49:28

马斯克嘲讽油车的时候,大多数车主却发现修不起电车了

特斯拉的CEO马斯克日前再对燃油车发出激烈言论&#xff0c;认为传统汽车已走向衰落和死亡&#xff0c;这样说法恐怕有失偏颇&#xff0c;原因是他显然没有考虑到消费者对汽车的使用成本是如此看重&#xff0c;其中的制造技术之一的一体化压铸就在国内外引发不小的争论。普遍来说…

作者头像 李华
网站建设 2026/6/9 23:20:13

基于WinDbg下载的内核调试完整指南

深入Windows内核调试&#xff1a;从WinDbg下载到实战排错的完整路径 你有没有遇到过这样的场景&#xff1f;系统毫无征兆地蓝屏&#xff0c;错误码一闪而过&#xff0c;事件查看器里只留下一行模糊的“KERNEL_SECURITY_CHECK_FAILURE”&#xff1b;或者你在开发一个NDIS驱动&am…

作者头像 李华
网站建设 2026/6/2 2:35:35

从零实现STM32开发:Keil5安装教程完整示例

从零搭建STM32开发环境&#xff1a;Keil5安装实战全解析 你是不是也曾对着电脑屏幕发愁——明明下载了Keil5&#xff0c;点击“编译”却提示找不到芯片&#xff1f;插上ST-Link&#xff0c;调试时却弹出“Cannot access target”&#xff1f;别急&#xff0c;这并不是你代码的…

作者头像 李华
网站建设 2026/6/15 8:28:05

智能绩效管理AI平台的大模型应用:架构师的3个落地场景

智能绩效管理AI平台的大模型应用&#xff1a;架构师的3个落地场景 元数据框架 标题 智能绩效管理AI平台的大模型应用&#xff1a;架构师的3个落地场景——从目标对齐到归因推理的智能化闭环设计 关键词 大模型应用&#xff1b;智能绩效管理&#xff1b;目标对齐&#xff1b;因果…

作者头像 李华