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);
  }
}

五、思维导图


目录
相关文章
|
10天前
|
算法 网络安全 区块链
2023/11/10学习记录-C/C++对称分组加密DES
本文介绍了对称分组加密的常见算法(如DES、3DES、AES和国密SM4)及其应用场景,包括文件和视频加密、比特币私钥加密、消息和配置项加密及SSL通信加密。文章还详细展示了如何使用异或实现一个简易的对称加密算法,并通过示例代码演示了DES算法在ECB和CBC模式下的加密和解密过程,以及如何封装DES实现CBC和ECB的PKCS7Padding分块填充。
31 4
2023/11/10学习记录-C/C++对称分组加密DES
|
11天前
|
算法 C语言 C++
【c++丨STL】list的使用
本文介绍了STL容器`list`的使用方法及其主要功能。`list`是一种双向链表结构,适用于频繁的插入和删除操作。文章详细讲解了`list`的构造函数、析构函数、赋值重载、迭代器、容量接口、元素访问接口、增删查改操作以及一些特有的操作接口如`splice`、`remove_if`、`unique`、`merge`、`sort`和`reverse`。通过示例代码,读者可以更好地理解如何使用这些接口。最后,作者总结了`list`的特点和适用场景,并预告了后续关于`list`模拟实现的文章。
27 7
|
19天前
|
存储 编译器 C++
C++ initializer_list&&类型推导
在 C++ 中,`initializer_list` 提供了一种方便的方式来初始化容器和传递参数,而右值引用则是实现高效资源管理和移动语义的关键特性。尽管在实际应用中 `initializer_list&&` 并不常见,但理解其类型推导和使用方式有助于深入掌握现代 C++ 的高级特性。
16 4
|
2月前
|
编译器 C语言 C++
配置C++的学习环境
【10月更文挑战第18天】如果想要学习C++语言,那就需要配置必要的环境和相关的软件,才可以帮助自己更好的掌握语法知识。 一、本地环境设置 如果您想要设置 C++ 语言环境,您需要确保电脑上有以下两款可用的软件,文本编辑器和 C++ 编译器。 二、文本编辑器 通过编辑器创建的文件通常称为源文件,源文件包含程序源代码。 C++ 程序的源文件通常使用扩展名 .cpp、.cp 或 .c。 在开始编程之前,请确保您有一个文本编辑器,且有足够的经验来编写一个计算机程序,然后把它保存在一个文件中,编译并执行它。 Visual Studio Code:虽然它是一个通用的文本编辑器,但它有很多插
|
2月前
|
存储 搜索推荐 C++
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
66 2
|
2月前
|
存储 算法 C++
【C++打怪之路Lv10】-- list
【C++打怪之路Lv10】-- list
23 1
|
2月前
|
存储 C++ 容器
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器1
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
71 5
|
2月前
|
Java 编译器 C++
c++学习,和友元函数
本文讨论了C++中的友元函数、继承规则、运算符重载以及内存管理的重要性,并提到了指针在C++中的强大功能和使用时需要注意的问题。
30 1
|
2月前
|
存储 编译器 C++
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
83 2
|
2月前
|
存储 缓存 C++
C++番外篇——list与vector的比较
C++番外篇——list与vector的比较
28 0