马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
注:终极代码以汇总的为准
1.前言
在之前的数据布局中,我们曾模拟实现过链表的数据布局,但是非常贫苦,全篇都袒露了链表的底层布局-----指针,但是从利用的角度,利用者并不关心你用的底层布局是啥,而且编写者也不肯意将所有的底层布局暴袒露来,为此,在此文章中,我们将充分发挥c++的上风,将指针包装一下,变为迭代器
2.根本框架的实现
根本布局包罗链表的创建,包罗链表结点的创建,结点的初始化,以及对底层布局----指针的封装,还有一些根本操作,例如++,==,!=,还有解引用操作等。
我们将造链表的文件放在List.h文件中,等下在test.cpp文件中进行测试。
如下代码是根本的布局代码:(具体功能没实现)
- #include <assert.h>
- namespace rens
- {
- 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>
- struct list_iterator
- {
- typedef list_node<T> Node;
- Node* _node;
- list_iterator(Node* node)
- :_node(node)
- {}
- T& operator*() //模拟指针的解引用
- {
- return _node->_data; //返回的是数据,类型为T
- }
- T* operator->() //解引用的->,这个较为特殊
- {
- return &_node->_data;
- }
- list_iterator<T>& operator++()
- {
- _node = _node->_next;
- return *this; //++操作返回的是下一个结点
- }
- bool operator!=(const list_iterator<T>& it)
- {
- return this->_node != it._node;
- }
- bool operator==(const list_node<T>& it)
- {
- return this->_node == it._node;
- }
- };
- template <class T>
- class list
- {
- typedef list_node<T> Node;
- public:
- typedef list_iterator<T> iterator;
- private:
- Node* _head;
- size_t _size;
- };
复制代码 但是,上述代码假如要是想遍历const对象是,由于我们的迭代器不是const迭代器,不能满足我们的需求,为此我们还要将上述代码cv一份,并改为const迭代器。
const迭代器代码如下:
- template <class T>
- struct const_list_iterator
- {
- typedef list_node<T> Node;
- Node* _node;
- const_list_iterator(Node* node)
- :_node(node)
- {}
- const T& operator*() //模拟指针的解引用
- {
- return _node->_data; //返回的是数据,类型为T
- }
- const T* operator->() //解引用的->,这个较为特殊
- {
- return &_node->_data;
- }
- const_list_iterator<T>& operator++()
- {
- _node = _node->_next;
- return *this; //++操作返回的是下一个结点
- }
- bool operator!=(const const_list_iterator<T>& it)
- {
- return this->_node != it._node;
- }
- bool operator==(const const_list_iterator<T>& it)
- {
- return this->_node == it._node;
- }
- };
复制代码 但是,通过对比(对比图如下),我们发现这两段代码重复度太大了,仅仅是返回类型的区别,如许写未免太浪费,所以我们将其改造一下!

改造想法:既然我们的类型就是有无const的区别,那我们不妨利用模板,对其进行改造,添加一个Ref,即reference,引用&以及Ptr,即pointer,指针
为了方便改造,我们将原来的list_iterator<T>给typedef一下,省的总改!
改造代码:
- 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* node)
- :_node(node)
- {}
- Ref operator*() //模拟指针的解引用
- {
- return _node->_data; //返回的是数据,类型为T
- }
- Ptr operator->() //解引用的->,这个较为特殊
- {
- return &_node->_data;
- }
- self& operator++() //前置++,返回的是引用, this指向的对象不销毁。
- {
- _node = _node->_next;
- return *this; //++操作返回的是下一个对象
- }
- self operator++(int) //后置++,返回的是一个临时对象,tmp出函数就销毁了
- {
- 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& it)
- {
- return this->_node != it._node;
- }
- bool operator==(const self& it)
- {
- return this->_node == it._node;
- }
- };
复制代码 别的功能的实现:
3.代码的汇总及实现
这是List.h文件
- #include <assert.h>#include <initializer_list>#include<iostream>#include<algorithm>namespace rens{ 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* node) :_node(node) {} Ref operator*() //模拟指针的解引用 { return _node->_data; //返回的是数据,类型为T } Ptr operator->() //解引用的->,这个较为特殊 { return &_node->_data; } self& operator++() //前置++,返回的是引用, this指向的对象不烧毁。 { _node = _node->_next; return *this; //++操作返回的是下一个对象 } self operator++(int) //后置++,返回的是一个临时对象,tmp出函数就烧毁了 { 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& it) { return this->_node != it._node; } bool operator==(const self& it) { return this->_node == it._node; } }; //template <class T> //struct list_iterator //{ // typedef list_node<T> Node; // Node* _node; // list_iterator(Node* node) // :_node(node) // {} // // T& operator*() //模拟指针的解引用 // { // return _node->_data; //返回的是数据,类型为T // } // // T* operator->() //解引用的->,这个较为特殊 // { // return &_node->_data; // } // // list_iterator<T>& operator++() // { // _node = _node->_next; // return *this; //++操作返回的是下一个结点 // } // // bool operator!=(const list_iterator<T>& it) // { // return this->_node != it._node; // } // // bool operator==(const list_node<T>& it) // { // return this->_node == it._node; // } //}; //template <class T> //struct const_list_iterator //{ // typedef list_node<T> Node; // Node* _node; // const_list_iterator(Node* node) // :_node(node) // {} // // const T& operator*() //模拟指针的解引用 // { // return _node->_data; //返回的是数据,类型为T // } // // const T* operator->() //解引用的->,这个较为特殊 // { // return &_node->_data; // } // // const_list_iterator<T>& operator++() // { // _node = _node->_next; // return *this; //++操作返回的是下一个结点 // } // // bool operator!=(const const_list_iterator<T>& it) // { // return this->_node != it._node; // } // // bool operator==(const const_list_iterator<T>& it) // { // return this->_node == it._node; // } //}; template <class T>
- class list
- {
- typedef list_node<T> Node;
- public:
- //typedef list_iterator<T> iterator;
- typedef list_iterator<T, T&, T*> iterator;
- typedef list_iterator<T, const T&, const T*> const_iterator;
- iterator begin()
- {
- iterator it(_head->_next); //我们的链表是双向循环链表,_head可以理解为哨兵结点
- return it;
- }
- iterator end()
- {
- return iterator(_head);
- }
- const_iterator begin()const //加上const关键字表示该函数不会修改类的任何成员变量,即它是一个常量成员函数
- {
- return const_iterator(_head->_next);
- }
- const_iterator end()const
- {
- return const_iterator(_head);
- }
- void empty_init()
- {
- _head = new Node;
- _head->_next = _head;
- _head->_prev = _head;
- _size = 0;
- }
- list()
- {
- empty_init();
- }
- list(std::initializer_list<T> lt)
- {
- empty_init();
- for (auto& e : lt)
- {
- push_back(e);
- }
- }
- //lt2(lt1)
- list(const list<T>& lt)
- {
- empty_init();
- for (auto& e : lt)
- {
- push_back(e);
- }
- }
- //lt1=lt3
- list<T>& operator=(list<T> lt)
- {
- swap(lt);
- return *this;
- }
- void swap(list<T>& lt)
- {
- std::swap(_head, lt._head);
- std::swap(_size, lt._size);
- }
- ~list()
- {
- clear();
- delete _head;
- _head = nullptr;
- }
- void clear()
- {
- iterator it = begin();
- while (it != end())
- {
- it = erase(it);
- }
- }
- size_t size()const
- {
- return _size;
- }
- void push_back(const T& x)
- {
- insert(end(), x);
- }
- void push_front(const T& x)
- {
- insert(begin(), x);
- }
- void pop_front()
- {
- erase(begin());
- }
- void pop_back()
- {
- erase(--end());
- }
- void insert(iterator pos, const T& x)
- {
- Node* cur = pos._node;
- Node* prev = cur->_prev;
- Node* newnode = new Node(x);
- prev->_next = newnode;
- newnode->_prev = prev;
- newnode->_next = cur;
- cur->_prev = newnode;
- ++_size;
- }
- iterator erase(iterator pos)
- {
- assert(pos != end());
- Node* cur = pos._node;
- Node* nextnode = cur->_next;
- Node* prevnode = cur->_prev;
- prevnode->_next = nextnode;
- nextnode->_prev = prevnode;
- delete cur;
- --_size;
- return iterator(nextnode);
- }
- private:
- Node* _head;
- size_t _size;
- };
- }
复制代码 这是test.cpp文件
- #include"list.h"
- using namespace std;
- void test1()
- {
- rens::list<int> lt1;
- lt1.push_back(1);
- lt1.push_back(2);
- lt1.push_back(3);
- lt1.push_back(4);
- rens::list<int>::iterator it1 = lt1.begin();
- while (it1 != lt1.end())
- {
- *it1 += 1;
- cout << *it1 << " ";
- ++it1;
- }
- cout << endl;
- }
- void print(const rens::list<int>& lt)
- {
- // const迭代器本身可以修改,指向内容不能修改
- rens::list<int>::const_iterator it = lt.begin();
- while (it != lt.end())
- {
- cout << *it << " ";
- ++it;
- }
- cout << endl;
- }
- struct A
- {
- A(int a1=1,int a2=1)
- :_a1(a1)
- ,_a2(a2)
- {}
- int _a1;
- int _a2;
- };
- void test2()
- {
- rens::list<A> lt2;
- lt2.push_back({ 1,1 });
- lt2.push_back({ 2,2 });
- lt2.push_back({ 3,3 });
- lt2.push_back({ 4,4 });
- rens::list<A>::iterator it = lt2.begin();
- while (it != lt2.end())
- {
- cout << it->_a1 << "," << it->_a2 << endl;
- ++it;
- }
- cout << endl;
- rens::list<int> lt1;
- lt1.push_back(1);
- lt1.push_back(2);
- lt1.push_back(3);
- print(lt1);
- }
- void test3()
- {
- rens::list<int> lt1;
- lt1.push_back(1);
- lt1.push_back(2);
- lt1.push_back(3);
- lt1.push_back(4);
- for (auto e : lt1)
- {
- cout << e << " ";
- }
- cout << endl;
- lt1.push_front(5);
- lt1.push_front(6);
- for (auto e : lt1)
- {
- cout << e << " ";
- }
- cout << endl;
- lt1.pop_back();
- lt1.pop_back();
- lt1.pop_front();
- lt1.pop_front();
- for (auto e : lt1)
- {
- cout << e << " ";
- }
- cout << endl;
- lt1.pop_back();
- lt1.pop_back();
- for (auto e : lt1)
- {
- cout << e << " ";
- }
- cout << endl;
- }
- void test4()
- {
- rens::list<int> lt1;
- lt1.push_back(1);
- lt1.push_back(2);
- lt1.push_back(3);
- lt1.push_back(4);
- for (auto e : lt1)
- {
- cout << e << " ";
- }
- cout << endl;
- rens::list<int> lt2(lt1);
- lt1.clear();
- for (auto e : lt1)
- {
- cout << e << " ";
- }
- cout << endl;
- for (auto e : lt2)
- {
- cout << e << " ";
- }
- cout << endl;
- rens::list<int> lt3 = { 10,20,30,40 };
- lt1 = lt3;
- for (auto e : lt1)
- {
- cout << e << " ";
- }
- cout << endl;
- }
- int main()
- {
- //test1();
- //test2();
- //test3();
- test4();
- return 0;
- }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |