C++:迭代器与原生指针

4 篇文章 0 订阅
3 篇文章 0 订阅

一、模拟实现list迭代器

在STL中vector和string的迭代器都是使用的原生指针,但是由于双向链表不是连续的所以无法使用原生指针充当迭代器。所以,我们为list创建了一个自定义类型迭代器。首先创建一个类模板表示节点。

链表节点

//创建一个自定义类型模板作为节点;这个自定义类型的类型是ListNode<T>
    template <class T>
    struct ListNode {
        //创建指针指向前一个节点
        ListNode* _prev;
        //创建指针指向下一个节点
        ListNode* _next;
        //创建存储数据
        T _data;

        ListNode(const T& val = T()) :
            _prev(nullptr)
            , _next(nullptr)
            , _data(val)
        {}

    };

注意:

  • 普通自定义类的类型是类名;

  • 自定义类模板的类型是类名<T>,T根据实际情况确定;


自定义迭代器

//创建迭代器类模板
    template <class T>
    class _list_iterator {
        //重新定义变量名
        typedef ListNode<T> Node;
    //封装函数
    public:
        //最起码要有个构造函数吧,函数输入是结构体指针
        _list_iterator(Node*& x)
            :_node(x)
        {}

        //重载运算符++
        _list_iterator<T>& operator++() {
            _node = _node->_next;
            return *this;
        }

        _list_iterator<T> operator++(int) {
            _list_iterator tmp(*this);
            _node = _node->_next;
            return tmp;
        }

        //重载运算符*
        T& operator*() {
            return _node->_data;
        }

        //重载运算符!=
        bool operator !=(const _list_iterator& x) {
            return _node != x._node;
        }

        bool operator ==(const _list_iterator& x) {
            return _node == x._node;
        }
    //创建私有化成员变量
    private:
        //指针的成员变量应该是ListNode的指针
        Node* _node;
    };

注意:

  • 不需要析构函数 -- 节点不属于迭代器,不需要迭代器释放

  • 拷贝构造和赋值重载 -- 默认生成的浅拷贝就可以(迭代器本身就是指针压根不需要深拷贝)

  • 后加加需要一个int类型的参数,并且由于后加加返回的是临时变量,所以选择传值返回;


二、模拟实现list

list简单模拟实现


    //创建双向链表list类模板
    template <class T>
    class list {
        //重新定义变量名
        typedef ListNode<T> Node;
        //封装函数
    public:
        typedef _list_iterator<T> iterator;
        //创建一个无参构造器
        list() {
            //_phead只是一个野指针,现在初始化一块空间给它
            _head = new Node; //new之前会调用ListNode的构造函数初始化
            _head->_next = _head;//哨兵位上一个节点和下一个节点都是自己;
            _head->_prev = _head;
        }

        //迭代器起始位置
        iterator begin() {
            return iterator(_head->_next);
            //为什么是传值返回?iterator本质上还是指针,指向某一个节点。
            //这个节点的空间通过析构函数释放,iterator根本管不到
        }

        iterator end() {
            iterator tmp(_head);
            return tmp;
        }

        //尾插
        void push_back(const T& x) {
            //找到尾节点
            Node* tail = _head->_prev;
            //创建新节点
            Node* newnode = new Node(x);

            //调整节点指向
            tail->_next = newnode;
            newnode->_prev = tail;
            newnode->_next = _head;
            _head->_prev = newnode;
        }
    private:
        //哨兵位的指针
        Node* _head;

    };

验证迭代器

example:

void test_list1()
        {
            list<int> lt;
            lt.push_back(1);
            lt.push_back(2);
            lt.push_back(3);
            lt.push_back(4);

            list<int>::iterator it = lt.begin();
            while (it != lt.end())
            {
                std::cout << *it << " ";
                it++;
            }
            std::cout << std::endl;

        }

result:

1 2 3 4

三、迭代器与指针

example:

void fun() {
            //创建一个原生指针
            Node* pnode = _head->_next;
            //创建迭代器
            iterator it(_head->_next);

            *pnode;//对原生指针解引用
            *it;//对迭代器解引用

            ++pnode;//对原生指针++
            ++it;//对迭代器++
        }

result:

++之前:

++之后:

pnode是一个结构体指针而it是一个迭代器对象 ,他们占用的空间一样大都是4字节(32位系统),并且存的值也是一样的,但他们使用运算符的意义和结果不同。*pnode返回的是一个结构体List Node,it返回的是ListNode里面的_data;++之后pnode变成了野指针,it变成了指向下一个节点的迭代器。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一 杯 清 酒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值