C++ STL - list 模拟实现+解析迭代器

本文介绍了C++ STL中的list容器,包括其基本操作、模拟实现以及迭代器的工作原理。重点讨论了list的迭代器实现,包括const_iterator的问题和反向迭代器的设计,强调了list在插入删除操作上的高效性,并对比了list与vector的区别。

目录

list基本介绍和使用

list模拟实现

list的迭代器:

理解:

const_iterator问题:

list迭代器失效问题:

list的反向迭代器

理解: 

reverse_iterator.h

反向迭代器的operator*实现:

operator->() 

vector和list的比较


list基本介绍和使用

list - 带头双向循环链表。

对比vector,因为list是由一个个结点连接而成的,致使list
1. 不支持元素的随机访问,即没有operator[],因为效率低。访问元素front back
2. 没有capacity的概念,内存允许的情况下,可以无限申请节点并扩展
3. 支持push_front pop_front,使得list可以作为queue的适配容器
4. 最大的优势是在任意位置插入删除都可以在O(1)时间完成

学习成员函数 见https://cplusplus.com/reference/list/list/

list模拟实现

#ifndef STL_LIST_H
#define STL_LIST_H

#include <cstddef>   // size_t
#include <cassert>
#include <iostream>
#include "reverse_iterator.h"
//using namespace std;
namespace yzl
{
    template<class T>
    struct list_node  // list内部使用的结点类型
    {
    public:
        T _data;
        list_node<T>* _next;
        list_node<T>* _prev;
    public:
        list_node(const T& data = T())  // 结点的默认构造函数
        : _data(data), _next(nullptr), _prev(nullptr)
        { }
//        ~list_node() = default;
//        // 拷贝构造,其实没必要
//        list_node(const list_node<T>& node)
//        : _data(node._data), _next(node._next), _prev(node._prev)  // 浅拷贝
//        { }
//        // 赋值运算符重载,也没必要
//        list_node<T>& operator=(const list_node<T>& node)  // 浅拷贝
//        {
//            _data = node._data;
//            _prev = node._prev;
//            _next = node._next;
//            return *this;
//        }
    };

    // 说真的,只是对结点指针的一个封装罢了,构造函数也是通过一个结点指针即可构造出一个迭代器。
    // 对于迭代器的操作,其实也就是++ -- 然后解引用。目前的操作就是这些,之后再有再补充吧。
    template<class T, class Ref, class Ptr> // T&  T*  or  const T& const T*
    class __list_iterator  // 成员就是一个结点指针
    {
    public:
        typedef list_node<T> Node;  // 这是一个结构体,结点。Node就是一个结点结构体。
        typedef __list_iterator<T, Ref, Ptr> iterator;

        typedef std::bidirectional_iterator_tag iterator_category;
        typedef T value_type;
        typedef Ptr pointer;
        typedef Ref reference;
        typedef ptrdiff_t difference_type;
    public:
        Node* _node;  // 这个迭代器类型有一个数据成员,是结点指针。
    public:
        __list_iterator(Node* node)
        :_node(node)
        { }
        // 这个类型的实例化对象本身不支持解引用操作,operator*赋予了它解引用之后的操作。
        Ref operator*()
        {
            return _node->_data;
        }
        Ptr operator->()
        {
            return &(operator*());
//            return &(_node->_data);
        }
        bool operator!=(const iterator& it)
        {
            return _node != it._node;
        }
        bool operator==(const iterator& it)
        {
            return _node == it._node;
        }
        // 思考一下迭代器++,普通迭代器和const迭代器其实都可以++
        iterator& operator++() // 前置
        {
            _node = _node->_next;
            return *this;
        }
        iterator operator++(int)  // 后置
        {
            iterator tmp = *this;
            this->_node = this->_node->_next;
            return tmp;
        }

        iterator& operator--()
        {
            _node = _node->_prev;
            return *this;
        }
        iterator operator--(int)
        {
            iterator tmp(*this);
            this->_node = this->_node->_prev;
            return tmp;
        }
    };

    // list<int> ls;
    template<class T>
    class list
    {
    private:
        typedef list_node<T> Node;
        Node* _head;    // list_node<int>* _head;

    public:
        // 说真的,关于list的迭代器,你只需要实现begin end这一系列的即可,还要让它的返回值支持++ 解引用操作,这就够了,说真的。
        typedef __list_iterator<T, T&, T*> iterator;   // 这个结构体别名为迭代器,本身是不支持解引用操作的。
        //typedef const __list_iterator<T> const_iterator;  // 你这里const修饰的是迭代器类型,他有结点指针数据成员,const使得结点指针不能改变。
        // 但是根本上,const迭代器是指不能修改*迭代器所指的值。而不是迭代器本身。
        typedef __list_iterator<T, const T&, const T*> const_iterator;

//        typedef __list_reverse_iterator<T, T&, T*> reverse_iterator;
//        typedef __list_reverse_iterator<T, const T&, const T*> const_reverse_iterator;
        typedef __reverse_iterator<__list_iterator<T, T&, T*>, T&, T*> reverse_iterator;
        typedef __reverse_iterator<const_iterator, const T&, const T*> const_rever
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值