c++的学习之路:16、list(3)

简介: c++的学习之路:16、list(3)

一、赋值重载

这里的赋值重载就是直接利用交换函数进行把传参生成的临时数据和需要进行赋值的交换就可以了,代码与测试如下。

list& operator=(list lt)
        {
            swap(lt);
            return *this;
        }


二、带模板的创建

这里是直接把初始化单独拿出来做一个函数,其他的和上篇文章中写vector差不多,都是利用swap去交换临时生成的参数和需要初始化的链表,代码和测试结果如图。

void empty_init()
        {
            _head = new node;
            _head->_next = _head;
            _head->_prev = _head;
        }
        void swap(list& tmp)
        {
            std::swap(_head, tmp._head);
        }
        list()
        {
            empty_init();
        }
        template 
        list(Iterator first, Iterator last)
        {
            empty_init();
            while (first != last)
            {
                push_back(*first);
                ++first;
            }
        }
        list(const list& lt)
        {
            empty_init();
            list tmp(lt.begin(), lt.end());
            swap(tmp);
        }

三、析构函数

这里是写了一个清理的函数,就是利用迭代器和后置++进行erase掉节点,最后再把头节点也就是哨兵位节点删除掉就可以了,代码和测试如下。

~list()
        {
            clear();
            delete _head;
            _head = nullptr;
        }
        void clear()
        {
            iterator it = begin();
            while (it != end())
            {
                erase(it++);
            }
        }

四、代码

#pragma once
#include <assert.h>
namespace ly
{
  template<class T>
  struct list_node
  {
    list_node<T>* _next;
    list_node<T>* _prev;
    T _data;
 
    list_node(const T& x = T())
      :_next(nullptr)
      , _prev(nullptr)
      , _data(x)
    {}
  };
 
  template<class T, class Ref, class Ptr>
  struct _list_iterator
  {
    typedef list_node<T> node;
    typedef _list_iterator<T, Ref, Ptr> self;
    node* _node;
 
    _list_iterator(node* n)
      :_node(n)
    {}
 
    Ref operator*()
    {
      return _node->_data;
    }
 
    Ptr operator->()
    {
      return& _node->_data;
    }
 
    self& operator++()
    {
      _node = _node->_next;
      return *this;
    }
 
    self operator++(int)
    {
      self tmp(*this);
      _node = _node->_next;
      return tmp;
    }
 
    self& operator--()
    {
      _node = _node->_prev;
      return *this;
    }
 
    self operator--(int)
    {
      self tmp(*this);
      _node = _node->_prev;
      return tmp;
    }
 
    bool operator==(const self& s)
    {
      return _node == s._node;
    }
 
    bool operator!=(const self& s)
    {
      return _node != s._node;
    }
  };
 
  template<class T>
  class list
  {
  public:
    typedef list_node<T> node;
    typedef _list_iterator<T, T&, T*> iterator;
    typedef _list_iterator<T, const T&, const T*> const_iterator;
 
    void empty_init()
    {
      _head = new node;
      _head->_next = _head;
      _head->_prev = _head;
    }
 
    void swap(list<T>& tmp)
    {
      std::swap(_head, tmp._head);
    }
 
    list()
    {
      empty_init();
    }
 
    template <class Iterator>
    list(Iterator first, Iterator last)
    {
      empty_init();
      while (first != last)
      {
        push_back(*first);
        ++first;
      }
    }
 
    list(const list<T>& lt)
    {
      empty_init();
 
      list<T> tmp(lt.begin(), lt.end());
      swap(tmp);
    }
 
    ~list()
    {
      clear();
      delete _head;
      _head = nullptr;
    }
 
    void clear()
    {
      iterator it = begin();
      while (it != end())
      {
        erase(it++);
      }
    }
 
    list<T>& operator=(list<T> lt)
    {
      swap(lt);
      return *this;
    }
 
    iterator begin()
    {
      return iterator(_head->_next);
    }
 
    iterator end()
    {
      return iterator(_head);
    }
    
    const_iterator begin() const
    {
      return const_iterator(_head->_next);
    }
 
    const_iterator end() const
    {
      return const_iterator(_head);
    }
 
    void push_back(const T& x)
    {
      insert(end(),x);
    }
 
    void push_front(const T& x)
    {
      insert(begin(), x);
    }
 
    void pop_back()
    {
      erase(--end());
    }
 
    void pop_front()
    {
      erase(begin());
    }
 
    void insert(iterator pos,const T& x)
    {
      node* cur = pos._node;
      node* prev = cur->_prev;
      node* new_node = new node(x);
      prev->_next = new_node;
      new_node->_prev = prev;
      new_node->_next = cur;
      cur->_prev = new_node;
    }
 
    void erase(iterator pos)
    {
      assert(pos != end());
      node* prev = pos._node->_prev;
      node* next = pos._node->_next;
      prev->_next = next;
      next->_prev = prev;
      delete pos._node;
    }
 
  private:
    node* _head;
  };
 
  void print(list<int> l)
  {
    list<int>::iterator it = l.begin();
    while (it != l.end())
    {
      cout << *it << ' ';
      it++;
    }
    cout << endl;
  }
 
  void Test1()
  {
    list<int> l1;
    l1.push_back(1);
    l1.push_back(2);
    l1.push_back(3);
    l1.push_back(4);
    print(l1);
    l1.push_front(5);
    l1.push_front(6);
    l1.push_front(7);
    l1.push_front(8);
    print(l1);
    l1.pop_back();
    l1.pop_back();
    print(l1);
    l1.pop_front();
    l1.pop_front();
    print(l1);
  }
 
  void Test2()
  {
    list<int> l1;
    l1.push_back(1);
    l1.push_back(2);
    l1.push_back(3);
    l1.push_back(4);
    print(l1);
    list<int> l2(l1);
    print(l2);
    list<int> l3(l1.begin(), l1.end());
    print(l3);
  }
 
  void Test3()
  {
    list<int> l1;
    l1.push_back(1);
    l1.push_back(2);
    l1.push_back(3);
    l1.push_back(4);
    list<int> l2;
    l2.push_back(10);
    l2.push_back(20);
    l2.push_back(30);
    l2.push_back(40);
    print(l1);
    print(l2);
    l1.swap(l2);
    print(l1);
    print(l2);
  }
}

五、思维导图


目录
相关文章
|
25天前
|
编译器 C语言 C++
配置C++的学习环境
【10月更文挑战第18天】如果想要学习C++语言,那就需要配置必要的环境和相关的软件,才可以帮助自己更好的掌握语法知识。 一、本地环境设置 如果您想要设置 C++ 语言环境,您需要确保电脑上有以下两款可用的软件,文本编辑器和 C++ 编译器。 二、文本编辑器 通过编辑器创建的文件通常称为源文件,源文件包含程序源代码。 C++ 程序的源文件通常使用扩展名 .cpp、.cp 或 .c。 在开始编程之前,请确保您有一个文本编辑器,且有足够的经验来编写一个计算机程序,然后把它保存在一个文件中,编译并执行它。 Visual Studio Code:虽然它是一个通用的文本编辑器,但它有很多插
|
1月前
|
存储 搜索推荐 C++
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
50 2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
|
1月前
|
存储 算法 C++
【C++打怪之路Lv10】-- list
【C++打怪之路Lv10】-- list
20 1
|
1月前
|
存储 C++ 容器
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器1
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
54 5
|
1月前
|
Java 编译器 C++
c++学习,和友元函数
本文讨论了C++中的友元函数、继承规则、运算符重载以及内存管理的重要性,并提到了指针在C++中的强大功能和使用时需要注意的问题。
21 1
|
1月前
|
存储 编译器 C++
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
55 2
|
1月前
|
C++
【C++】C++ STL 探索:List使用与背后底层逻辑(三)
【C++】C++ STL 探索:List使用与背后底层逻辑
|
1月前
|
C++
【C++】C++ STL 探索:List使用与背后底层逻辑(二)
【C++】C++ STL 探索:List使用与背后底层逻辑
|
1月前
|
存储 缓存 C++
C++番外篇——list与vector的比较
C++番外篇——list与vector的比较
22 0
|
1月前
|
C++
C++番外篇——list的实现
C++番外篇——list的实现
19 0