重庆网站快速优化排名,聊城做网站价位,网站美工费用,云岭建设集团的网站个人主页~
list#xff08;上#xff09;~ list 四、模拟实现1、list.h#xff08;1#xff09;关于整个list的搭建①节点②迭代器③接口 #xff08;2#xff09;自定义类型实例化 2、test.cpp#xff08;1#xff09;test1#xff08;2#xff09;test2 五、额外小…
个人主页~
list上~ list 四、模拟实现1、list.h1关于整个list的搭建①节点②迭代器③接口 2自定义类型实例化 2、test.cpp1test12test2 五、额外小知识 四、模拟实现
1、list.h
#pragma once#include iostreamnamespace little_monster
{templateclass Tstruct list_node{T _data;list_nodeT* _prev;list_nodeT* _next;list_node(const T x T()):_data(x),_prev(nullptr),_next(nullptr){}};templateclass T,class Ref,class Ptrstruct __list_iterator{typedef list_nodeT Node;typedef __list_iteratorT, Ref, Ptr self;Node* _node;__list_iterator(Node* n):_node(n){}self operator(){_node _node-_next;return *this;}self operator--(){_node _node-_prev;return *this;}self operator(int){self tmp(*this);_node _node-_next;return tmp;}self operator--(int){self tmp(*this);_node _node-_prev;return tmp;}Ref operator*(){return _node-_data;}Ptr operator-(){return _node-_data;}bool operator!(const self s){return _node ! s._node;}bool operator(const self s){return _node s._node;}};templateclass Tclass list{typedef list_nodeT Node;public:typedef __list_iteratorT, T, T* iterator;typedef __list_iteratorT, const T, const T* const_iterator;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 Init_empty(){_head new Node;_head-_next _head;_head-_prev _head;_size 0;}list(){Init_empty();}list(const listT lt){Init_empty();for (auto e : lt){push_back(e);}}void swap(listT lt){std::swap(_head, lt._head);std::swap(_size, lt._size);}listint operator(listint lt){swap(lt);return *this;}~list(){clear();delete _head;_head nullptr;_size 0;}void clear(){iterator it begin();while (it ! end()){it erase(it);}}void push_back(const T x){insert(end(), x);}void pop_back(){erase(--end());}void push_front(const T x){insert(begin(), x);}void pop_front(){erase(begin());}iterator insert(iterator pos, const T x){Node* cur pos._node;Node* newnode new Node(x);Node* prev cur-_prev;prev-_next newnode;newnode-_prev prev;newnode-_next cur;cur-_prev newnode;_size;return iterator(newnode);}iterator erase(iterator pos){Node* cur pos._node;Node* prev cur-_prev;Node* next cur-_next;delete cur;prev-_next next;next-_prev prev;--_size;return iterator(next);}size_t size(){return _size;}private:Node* _head;size_t _size;};
}1关于整个list的搭建
①节点
节点是一个struct封装的类由数据、指向前一个位置的指针、指向后一个位置的指针、构造函数共同构成创建的是一个独立的节点初始化指针都为空
②迭代器
迭代器是一个struct封装的类由构造函数、自增自减、解引用、判断相等接口构成其中Ptr接受指针Ref接受引用
其中operator* 和operator-之前没有见过operator* 很简单返回的是该节点的值data也就是解引用的作用然后operator-为了增加代码的可读性其实是省略了一个-当A-_data时其实是A.operator-()-_data然后这里的A.operator-()返回的是A的指针然后通过间接访问符-访问_data
其中有关于迭代器的类型
在list中迭代器的三个模版参数分别为T、T、T*也就是说这个迭代器有该类型该类型的引用和该类型的指针三个模版参数这里就是将有关于迭代器的功能全部封装在里边因为在以前的学习中包括string和vector它们的迭代器都是原生态指针这里对于迭代器的要求更加复杂因为对于string和vector来说它们的存储空间是连续的而list是不连续的
③接口
接口就是常规的接口包括构造、拷贝构造、析构、增删查改函数增删查改的接口直接复用的insert和erase对于构造函数和拷贝构造函数我们封装了一个Init_empty函数用来生成头结点
2自定义类型实例化
struct AA
{AA(int a1 0, int a2 0):_a1(a1), _a2(a2){}int _a1;int _a2;
};void test3()
{listAA lt;lt.push_back(AA(1, 1));lt.push_back(AA(2, 2));lt.push_back(AA(3, 3));auto it lt.begin();while (it ! lt.end()){std::cout (*it)._a1 (*it)._a2 std::endl;std::cout it-_a1 it-_a2 std::endl;std::cout it.operator-()-_a1 it.operator-()-_a1 std::endl;it;}std::cout std::endl;}如果是自定义类型的话访问其中的元素就需要访问操作符来进行访问这里有三种方式进行访问都是通过被封装的迭代器进行的
2、test.cpp
1test1
测试尾插构造以及拷贝构造
void test1()
{listint lt1;lt1.push_back(1);lt1.push_back(2);lt1.push_back(3);lt1.push_back(4);lt1.push_back(5);listint lt2(lt1);for (auto e : lt1){std::cout e ;}std::cout std::endl;for (auto e : lt2){std::cout e ;}std::cout std::endl;
}2test2
void test2()
{listint lt1;lt1.push_back(1);lt1.push_back(2);lt1.push_back(3);lt1.push_back(4);lt1.push_back(5);lt1.insert(lt1.begin(), 6);lt1.insert(--lt1.end(), 7);for (auto e : lt1){std::cout e ;}std::cout std::endl;lt1.erase(lt1.begin());lt1.erase(--lt1.end());for (auto e : lt1){std::cout e ;}std::cout std::endl;
}这里解释一下insert是插入指定位置前面一个元素也就是说6插入到了2前面7插入到了5前面 erase是删除指定位置的元素也就是第二个元素以及头结点前一个元素分别是6和5
五、额外小知识
有关于内置类型也会调用构造函数这件事
void test4()
{int* p new int;*p 1;//int* p new int(1);//上面和这句结果是相同的过程不同一个是在构造后进行赋值一个是初始化列表赋初值 AA* ptr new AA;ptr-_a1 1;
}前面的文章提到过这件事因为它套用了模版模版当然也要兼容内置类型所以内置类型在构造时可以使用类似自定义类型构造的形式这样也会类似于调用模版函数 今日分享到这里~