C++ 全栈知识体系C++ 全栈知识体系
✿导航
  • 基础
  • 函数
  • 知识点
  • IO框架
  • 新版本特性
  • 数据库原理
  • SQL语言
  • SQL - MySQL
  • NoSQL - Redis
  • NoSQL - ElasticSearch
  • 算法基础
  • 常见算法
  • 领域算法
  • 分布式算法
  • 数据结构与算法
  • 计算机网络
  • 操作系统
  • 计算机组成
  • 开发
  • 测试
  • 架构基础
  • 分布式系统
  • 微服务
  • 中间件
  • 概念
  • 理论
  • 架构设计原则
  • 设计模式
  • 协议
  • 技术选型
  • 编码规范
  • 流水线构建 - CI/CD
  • 知识点 - Linux
  • 网站 - Nginx
  • 容器化 - Docker
  • 容器编排 - Kubernetes
  • 服务网格 - Service Mesh Istio
  • 常用快捷键 - Shortcut
  • 工具使用 - Tools
  • 开源项目
  • 学习项目
  • 个人项目
  • 项目开发
  • 项目Idea
  • 并发
  • 部署
  • 分布式
  • 知识
  • 问题
  • 编程语言与技术
  • 系统与架构
  • 软件开发实践
  • 数据处理与应用设计
  • 个人
  • 产品
  • 团队
  • 知识体系
  • Vue
关于
✿导航
  • 基础
  • 函数
  • 知识点
  • IO框架
  • 新版本特性
  • 数据库原理
  • SQL语言
  • SQL - MySQL
  • NoSQL - Redis
  • NoSQL - ElasticSearch
  • 算法基础
  • 常见算法
  • 领域算法
  • 分布式算法
  • 数据结构与算法
  • 计算机网络
  • 操作系统
  • 计算机组成
  • 开发
  • 测试
  • 架构基础
  • 分布式系统
  • 微服务
  • 中间件
  • 概念
  • 理论
  • 架构设计原则
  • 设计模式
  • 协议
  • 技术选型
  • 编码规范
  • 流水线构建 - CI/CD
  • 知识点 - Linux
  • 网站 - Nginx
  • 容器化 - Docker
  • 容器编排 - Kubernetes
  • 服务网格 - Service Mesh Istio
  • 常用快捷键 - Shortcut
  • 工具使用 - Tools
  • 开源项目
  • 学习项目
  • 个人项目
  • 项目开发
  • 项目Idea
  • 并发
  • 部署
  • 分布式
  • 知识
  • 问题
  • 编程语言与技术
  • 系统与架构
  • 软件开发实践
  • 数据处理与应用设计
  • 个人
  • 产品
  • 团队
  • 知识体系
  • Vue
关于
  • 编程语言与技术

    • Effective C++: 改善程序与设计的55个具体做法

      • 第2章 - 构造/析构/赋值运算(一)
      • 第2章 - 构造/析构/赋值运算(二)
      • 第2章 - 构造/析构/赋值运算(三)
      • 第3章 - 资源管理
      • 第4章 - 设计与声明(一)
      • 第4章 - 设计与声明(二)
      • 第5章 - 实现(一)
      • 第5章 - 实现(二)
      • 第6章 - 继承与面向对象设计
      • 第7章 - 模板与泛型编程
    • 深度探索C++对象模型

      • 第1章 - 关于对象
      • 第2章 - 构造函数语意学
      • 第3章 - Data 语意学
    • STL源码剖析

      • 第1章 - STL概论和版本简介
      • 第2章 - 空间配置器
      • 第3章 - 迭代器(iterators)概念与traits编程技法(一)
      • 第3章 - 迭代器(iterators)概念与traits编程技法(二)
      • 第4章 - 序列式容器 vector
      • 第4章 - 序列式容器 list
      • 第4章 - 序列式容器 deque
      • 第4章 - 序列式容器 stack和queue
      • 第4章 - 序列式容器 heap
      • 第4章 - 序列式容器 priority_queue
      • 第4章 - 序列式容器 slist
      • 第5章 - 关联式容器 RB-tree
      • 第5章 - 关联式容器 set和map
      • 第5章 - 关联式容器 hashtable
      • 第6章 - 算法
      • 第6章 - 算法之set
      • 第7章 - 仿函数
      • 第8章 - 配接器
  • 系统与架构

    • 深入理解计算机系统

      • 第1章 - 计算机系统漫游
      • 第2章 - 信息的表示和处理
      • 第3章 - 程序的机器级表示
      • 第5章 - 优化程序性能
      • 第6章 - 存储器层次结构
      • 第7章 - 链接
      • 第8章 - 异常控制流
      • 第9章 - 虚拟内存
      • 第10章 - 系统级I/O
      • 第11章 - 网络编程
      • 第12章 - 并发编程
    • 大型网站技术架构——核心原理与案例分析

      • 第1章 - 大型网站架构演化
      • 第2章 - 大型网站架构模式
      • 第3章 - 大型网站核心架构要素
      • 第4章 - 瞬时响应:网站的高性能架构
      • 第5章 - 万无一失:网站的高可用架构
      • 第6章 - 永无止境:网站的伸缩性架构
      • 第7章 - 随需应变:网站的可扩展架构
      • 第8章 - 固若金汤:网站的安全架构
    • 从零开始学架构

      • 架构基础
      • 架构设计原则
      • 高性能架构
      • 高可用架构
    • 程序员的自我修养————链接、装载与库

      • 第1章 - 简介
      • 第2章 - 静态链路
      • 第3章 - 目标文件里有什么
      • 第4章 - 静态链接
      • 第7章 - 动态链接
      • 第8章 - 共享库版本
      • 第10章 - 内存
      • 第11章 - 运行库
      • 第12章 - 系统调用与API
      • 第13章 - 运行库实现
  • 软件开发实践

    • 重构改善既有代码的设计

      • 第1章 - 重构,第一个示例
      • 第2章 - 重构的原则
      • 第3章 - 代码的坏味道
      • 第5章 - 重构列表
      • 第6章 - 重新组织函数
      • 第7章 - 在对象之间搬移特性
      • 第8章 - 重新组织数据
      • 第9章 - 简化条件表达式
      • 第10章 - 简化函数调用
      • 第11章 - 处理概括关系
      • 第12章 - 设计之大型重构
    • 代码大全2

      • 第1章 - 欢迎进入软件构建的世界
      • 第2章 - 用隐喻来更充分地理解软件开发
      • 第3章 - 三思而后行: 前期准备
      • 第4章 - 关键的构建决策
      • 第5章 - 软件构建中的设计
    • Linux多线程服务端编程——使用muduo C++ 网络库

      • Buffer类的设计
      • 设计与实现
      • 定时器与TimerQueue
      • Protobuf网络传输和Protobuf编解码器与消息分发器
      • EventLoop类剖析
      • EventLoopThread和EventLoopThreadPool剖析
      • TCP网络库和核心类
      • Connector剖析
      • TcpClient剖析
      • 学习总结
      • timing wheel
      • 消息广播服务
      • 线程安全的对象生命期管理
  • 数据处理与应用设计

    • 数据密集型应用系统设计

      • 第1章 - 可靠、可扩展与可维护的应用系统
      • 第2章 - 数据模型与查询语言
      • 第3章 - 数据存储与检索
      • 第4章 - 数据编码与演化
      • 第5章 - 数据复制
      • 第6章 - 数据分区
      • 第7章 - 事务

第4章:序列式容器 slist

    slist概述

    SGI STL另提供一个单向链表slist。slist和list的主要差别在于,前者的迭代器属于单向的Forward Iterator,后者的迭代器属于双向的BidirectionalIterator。根据STL的习惯,插入操作会将新元素插入于指定位置之前。**作为单向链表,slist没有任何方便的方法可以回头定出前一个位置,因此它必须从头找起。**为此,slist特别提供了insert_after和erase_after函数供灵活调用。

    insert函数的实现如下,__slist_previous函数可以根据头节点_M_head和位置节点__pos找到__pos之前的那个节点,然后调用_M_insert_after函数,实际调用__slist_make_link,在__pos-1节点后创建以__x为值的节点:

    islist.insert(ite, 99); 
    
    iterator insert(iterator __pos, const value_type& __x) {
        return iterator(_M_insert_after(__slist_previous(&this->_M_head,
                                                         __pos._M_node),
                        __x));
    }
    
    inline _Slist_node_base* __slist_previous(_Slist_node_base* __head,
                     const _Slist_node_base* __node)
    {
      while (__head && __head->_M_next != __node)
        __head = __head->_M_next;
      return __head;
    }
    
    _Node* _M_insert_after(_Node_base* __pos, const value_type& __x) {
        return (_Node*) (__slist_make_link(__pos, _M_create_node(__x)));
    

    slist的节点

    slist的节点和迭代器设计架构如下:

    slist迭代器和节点设计

    slist的迭代器

    slist的迭代器可以用下图表示:

    slist迭代器

    slist的数据结构

    template<class T, class Alloc = alloc>
    class slist
    {
    public :
    	typedef	T	value_type ;
    	typedef	value_type*	pointer ; 
    	typedef	const	value_type*	const_pointer ;
    	typedef	value_type&	reference ;
    	typedef	const value_type& const_reference ;
    	typedef	size_t	size_type ;
    	typedef	ptrdiff_t	difference_type ;
     
     
    	typedef	__slist_iterator<T,T&,T*>	iterator ;
    	typedef	__slist_iterator<T,const T&,const T*> const_iterator ;
     
    private :
    	typedef	__slist_node<T>	list_node ;
    	typedef	__slist_node_base	list_node_base ;
    	typedef	__slist_iterator_base	iterator_base ;
    	typedef simple_alloc<list_node,Alloc> list_node_allocator ;
     
    	static	list_node* create_node(const value_type& x)
    	{
    		list_node* node = list_node_allocator:;allocate() ; //配置空间
    		__STL_TRY{
    			construct(&node->data,x) ;
    			node->next = 0 ;
    		}
    		__STL_UNWIND(list_node_allocator:;deallocate(node)) ;
    		return node ;
    	}
     
    	static void destroy_node(list_node* node)
    	{
    		destroy(&node->data) ; //将元素析构	
    		list_node_allocator::deallocate(node) ; //释放空间
    	}
     
    private :
    	list_node_base head  ; //头部。注意,它不是指针,是实物
    			
     
    public:
    	slist() {head.next = 0 ;} 
    	~slist(){clear() ;}
     
    public :
    	iterator begin() {return iterator((list_node*)head.next) ;}
    	iterator end() {return iteator(0) ;}
    	iterator size() {const __slist_size(head.next) ;}
    	bool empty() const {return head.next == 0 ;} 
     
    	//两个slist互换:只要将head交换互指即可
    	void swap(slist &L)
    	{
    		list_node_base* tmp = head.next;
    		head.next = L.head.next ;
    		L.head.next = tmp ;
    	}
     
    public :
    	//取头部元素
    	reference front() {return ((list_node*)head.next)->data ;}
     
    	//从头部插入元素(新元素成为slist的第一个元素)
    	void push_front(const value_type& x)
    	{
    		__slist_make_link(&head,create_node(x)) ;
    	}
     
    	//注意,没有push_back()
    	
    	//从头部取走元素(删除之)。修改head
    	void pop_front()
    	{
    		list_node* node = (list_node*)head.next ;
    		head.next = node->next ;
    		destroy_node(node);
    	}
    	.....
    }  ;
    

    slist的测试实例

    // file: 4slist-test.cpp
    
    // mingw64没有这个库
    //#include <slist>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    int main() {
        int i;
        slist<int> islist;
        cout << "size=" << islist.size() << endl;
        islist.push_front(9); 
        islist.push_front(1); 
        islist.push_front(2); 
        islist.push_front(3); 
        islist.push_front(4); 
        
        cout << "size=" << islist.size() << endl; 
    
        slist<int>::iterator ite =islist.begin(); 
        slist<int>::iterator ite2=islist.end(); 
        for(; ite != ite2; ++ite) 
            cout << *ite << ' ';  // 4 3 2 1 9
        cout << endl; 
    
        ite = find(islist.begin(), islist.end(), 1); //使用STL的find函数,可以找到1之前的那个迭代器
        if (ite!=0) 
            islist.insert(ite, 99); 
        cout << "size=" << islist.size() << endl;  // size=6
        cout << *ite << endl;     // 1
    
        ite =islist.begin(); 
        ite2=islist.end(); 
        for(; ite != ite2; ++ite) 
            cout << *ite << ' '; // 4 3 2 99 1 9 
        cout << endl; 
    
        ite = find(islist.begin(), islist.end(), 3); 
        if (ite!=0) 
            cout << *(islist.erase(ite)) << endl;  // 2
    
        ite =islist.begin(); 
        ite2=islist.end(); 
        for(; ite != ite2; ++ite) 
            cout << *ite << ' ';    // 4 2 99 1 9
        cout << endl; 
    }
    

    上述执行过程的示意图如下:

    slist-1

    slist-2

    slist-3

    Last Updated:
    Contributors: klc407073648
    Prev
    第4章 - 序列式容器 priority_queue
    Next
    第5章 - 关联式容器 RB-tree