当前位置: 首页 > news >正文

STL的list模拟实现(带移动构造和emplace版本)

  • list.h
#pragma once
#include<iostream>
#include<assert.h>
#include<algorithm>
#include"ReverseIterator.h"
#include<initializer_list>
#include <utility>using namespace std;//双向带头循环链表namespace bit
{template<class T>struct ListNode{ListNode* _next;ListNode* _prev;T _data;ListNode(const T& x=T()):_next(nullptr),_prev(nullptr),_data(x){}ListNode(T&& x):_next(nullptr), _prev(nullptr), _data(move(x)){}template<class... Args>ListNode(Args&&... args):_next(nullptr), _prev(nullptr), _data(std::forward<Args>(args)...){}};//法一:写两个类(带const和不带const)//template<class T>//struct ListConstIterator//{//	typedef ListNode<T> Node;//	typedef ListConstIterator<T> Self;//	Node* _node;//	ListConstIterator(Node* node)//		:_node(node)//	{}//	// *it//	const T& operator*()//	{//		return _node->_data;//	}//	const T* operator->()//	{//		return &(_node->_data);//	}//	// ++it//	Self& operator ++()//	{//		_node = _node->_next;//		return *this;//	}//	// it++//	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& it)//	{//		return _node != it._node;//	}//	bool operator ==(const Self& it)//	{//		return _node == it._node;//	}//};//法二:增加两个模板参数(编译器实例化生成了两个类)//正向迭代器template<class T,class Ref,class Ptr>struct ListIterator{typedef ListNode<T> Node;typedef ListIterator<T, Ref, Ptr> Self;Node* _node;ListIterator(Node* node):_node(node){}// *it//T& operator*()Ref operator*(){return _node->_data;}//T* operator->()Ptr operator->(){return &(_node->_data);}// ++itSelf& operator ++(){_node = _node->_next;return *this;}// it++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& it){return _node != it._node;}bool operator ==(const Self& it){return _node == it._node;}};////反向迭代器(法一:改写ListIterator类;法二:写一个适用所有容器的迭代器适配器)//template<class T, class Ref, class Ptr>//struct RListIterator//{//	typedef ListNode<T> Node;//	typedef RListIterator<T, Ref, Ptr> Self;//	Node* _node;//	RListIterator(Node* node)//		:_node(node)//	{}//	// *it//	//T& operator*()//	Ref operator*()//	{//		return _node->_data;//	}//	//T* operator->()//	Ptr operator->()//	{//		return &(_node->_data);//	}//	// ++it//	Self& operator ++()//	{//		_node = _node->_prev;//		return *this;//	}//	// it++//	Self operator ++(int)//	{//		Self tmp(*this);//浅拷贝不需要写拷贝构造//		_node = _node->_prev;//		return tmp;//	}//	Self& operator --()//	{//		_node = _node->_next;//		return *this;//	}//	Self operator --(int)//	{//		Self tmp(*this);//浅拷贝不需要写拷贝构造//		_node = _node->_next;//		return tmp;//	}//	bool operator!=(const Self& it)//	{//		return _node != it._node;//	}//	bool operator ==(const Self& it)//	{//		return _node == it._node;//	}//};template<class T>class list{typedef ListNode<T> Node;public://法一的typedef//typedef ListIterator<T> iterator;//typedef ListConstIterator<T> const_iterator;//法二的typedeftypedef ListIterator<T,T&,T*> iterator;typedef ListIterator<T,const T&,const T*> const_iterator;////反向迭代器的法一//typedef RListIterator<T, T&, T*> reverse_iterator;//typedef RListIterator<T, const T&, const T*> const_reverse_iterator;////反向迭代器的法二typedef ReverseIterator<iterator, T&, T*> reverse_iterator;typedef ReverseIterator<const_iterator, const T&, const T*> const_reverse_iterator;iterator begin(){return iterator(_head->_next);//可以直接写return _head->_next;//单参数构造函数可以隐式类型转换}iterator end(){return iterator(_head);}const_iterator begin()const{return const_iterator(_head->_next);}const_iterator end()const{return const_iterator(_head);}////反向迭代器的法一//reverse_iterator rbegin()//{//	return reverse_iterator(_head->_prev);//}//reverse_iterator rend()//{//	return reverse_iterator(_head);//}//const_reverse_iterator rbegin()const//{//	return const_reverse_iterator(_head->_prev);//}//const_reverse_iterator rend()const//{//	return const_reverse_iterator(_head);//}////反向迭代器的法二reverse_iterator rbegin(){return reverse_iterator(end());}reverse_iterator rend(){return reverse_iterator(begin());}const_reverse_iterator rbegin()const{return const_reverse_iterator(end());}const_reverse_iterator rend()const{return const_reverse_iterator(begin());}void empty_init(){_head = new Node;_head->_next = _head;_head->_prev = _head;_size = 0;}list(){empty_init();}list(initializer_list<T> il){empty_init();for (auto& e : il){push_back(e);}}list(const list<T>& lt){empty_init();for (auto& e : lt){push_back(e);}}void swap(list<T>& lt){std::swap(_head, lt._head);std::swap(_size, lt._size);}list<T>& operator=(list<T> lt){swap(lt);return *this;}void clear(){iterator it = begin();while (it != end()){it = erase(it);it++;}}~list(){clear();delete _head;_head = nullptr;}/*void push_back(const T& x){Node* newnode = new Node;Node* tail = _head->_prev;newnode->_data = x;tail->_next = newnode;newnode->_prev = tail;newnode->_next = _head;_head->_prev = newnode;}*/void push_back(const T& x){insert(end(), x);}void push_back(T&& x){insert(end(), move(x));}template<class... Args>void emplace_back(Args&&... args){emplace(end(), std::forward<Args>(args)...);}void push_front(const T& x){insert(begin(), x);}void push_front(T&& x){insert(begin(), move(x));}void pop_back(){erase(--end());}void pop_front(){erase(begin());}// 左值引用void insert(iterator pos,const T& val){Node* cur = pos._node;Node* newnode = new Node(val);Node* prev = cur->_prev;//prev newnode curprev->_next = newnode;newnode->_prev = prev;newnode->_next = cur;cur->_prev = newnode;_size++;}// 右值引用void insert(iterator pos, T&& val){//cout << "右值引用" << endl;Node* cur = pos._node;Node* newnode = new Node(move(val));Node* prev = cur->_prev;//prev newnode curprev->_next = newnode;newnode->_prev = prev;newnode->_next = cur;cur->_prev = newnode;_size++;}template<class... Args>void emplace(iterator pos, Args&&... args){//cout << "emplace" << endl;Node* cur = pos._node;Node* newnode = new Node(std::forward<Args>(args)...);Node* prev = cur->_prev;//prev newnode curprev->_next = newnode;newnode->_prev = prev;newnode->_next = cur;cur->_prev = newnode;_size++;}iterator erase(iterator pos){Node* cur = pos._node;Node* prev = cur->_prev;Node* next = cur->_next;prev->_next = next;next->_prev = prev;delete cur;_size--;return iterator(next);}size_t size()const{return _size;}bool empty()const{return _size==0;}private:Node* _head;size_t _size=0;};
  • ReverseIterator.h
#pragma once
//所有容器的反向迭代器
//迭代器适配器
namespace bit
{template<class Iterator,class Ref,class Ptr>struct ReverseIterator{Iterator _it;typedef ReverseIterator<Iterator, Ref, Ptr> Self;ReverseIterator(Iterator it):_it(it){}//T&Ref operator *(){Iterator tmp = _it;return *(--tmp);}//T*Ptr operator ->(){return &(operator *());//不能用_it->会报错}Self& operator ++(){--_it;return *this;}Self& operator --(){++_it;return *this;}bool operator !=(const Self& s){return _it != s._it;}};
}
  • Test.cpp
#define _CRT_SECURE_NO_WARNINGS 1#include"ReverseIterator.h"
#include"list.h"
#include<list>
#include<initializer_list>
#include<iostream>
#include<string>
#include <string.h>using namespace std;namespace bit
{// for testclass string{public:typedef char* iterator;typedef const char* const_iterator;iterator begin(){return _str;}iterator end(){return _str + _size;}const_iterator begin() const{return _str;}const_iterator end() const{return _str + _size;}string(const char* str = ""):_size(strlen(str)), _capacity(_size){cout << "string(char* str)-构造" << endl;_str = new char[_capacity + 1];strcpy(_str, str);}void swap(string& s){::swap(_str, s._str);::swap(_size, s._size);::swap(_capacity, s._capacity);}string(const string& s):_str(nullptr){cout << "string(const string& s) -- 拷贝构造" << endl;reserve(s._capacity);for (auto ch : s){push_back(ch);}}// 移动构造string(string&& s){cout << "string(string&& s) -- 移动构造" << endl;swap(s);}string& operator=(const string& s){cout << "string& operator=(const string& s) -- 拷贝赋值" <<endl;if (this != &s){_str[0] = '\0';_size = 0;reserve(s._capacity);for (auto ch : s){push_back(ch);}}return *this;}// 移动赋值string& operator=(string&& s){cout << "string& operator=(string&& s) -- 移动赋值" << endl;swap(s);return *this;}~string(){cout << "~string() -- 析构" << endl;delete[] _str;_str = nullptr;}char& operator[](size_t pos){assert(pos < _size);return _str[pos];}void reserve(size_t n){if (n > _capacity){char* tmp = new char[n + 1];if (_str){strcpy(tmp, _str);delete[] _str;}_str = tmp;_capacity = n;}}void push_back(char ch){if (_size >= _capacity){size_t newcapacity = _capacity == 0 ? 4 : _capacity *2;reserve(newcapacity);}_str[_size] = ch;++_size;_str[_size] = '\0';}string& operator+=(char ch){push_back(ch);return *this;}const char* c_str() const{return _str;}size_t size() const{return _size;}private:char* _str = nullptr;size_t _size = 0;size_t _capacity = 0;};
}void test1()
{//bit::test_list4();// //bit::list<int> lt ;//lt.push_back(1);//lt.push_back(2);//lt.push_back(3);//lt.push_back(4);bit::list<int>lt = { 1,2,3,4 };bit::list<int>::reverse_iterator rit = lt.rbegin();while (rit != lt.rend()){cout << *rit << " ";++rit;}cout << endl;
}void test2()
{bit::list<int> lt ;lt.push_front(1);lt.push_front(2);lt.push_front(3);lt.push_front(4);bit::list<int>::iterator it = lt.begin();while (it != lt.end()){cout << *it << " ";++it;}cout << endl;
}void test3()
{// 右值引用测试bit::list<string> lt;lt.push_front("a");lt.push_front("b");lt.push_front("c");lt.push_front("d");bit::list<string>::iterator it = lt.begin();while (it != lt.end()){cout << *it << " ";++it;}cout << endl;
}// 测试emplace
void test4()
{bit::list<bit::string> lt;// 传左值,跟push_back一样,走拷贝构造bit::string s1("111111111111");cout << "*********************************" << endl;lt.emplace_back(s1);cout << "*********************************" << endl;// 右值,跟push_back一样,走移动构造lt.emplace_back(move(s1));cout << "*********************************" << endl;// 直接把构造string参数包往下传,直接用string参数包构造string// 这里达到的效果是push_back做不到的lt.emplace_back("111111111111");cout << "*********************************" << endl << endl << endl;list<pair<bit::string, int>> lt1;// 跟push_back一样// 构造pair + 拷贝/移动构造pair到list的节点中data上pair<bit::string, int> kv("苹果", 1);lt1.emplace_back(kv);cout << "*********************************" << endl;// 跟push_back一样lt1.emplace_back(move(kv));cout << "*********************************" << endl;// 直接把构造pair参数包往下传,直接用pair参数包构造pair// 这里达到的效果是push_back做不到的//lt1.push_back({"苹果", 1 });lt1.emplace_back("苹果", 1);cout << "*********************************" << endl;
}int main()
{//test2();test4();cout << endl;return 0;
}
http://www.dtcms.com/a/407352.html

相关文章:

  • 当技术不再是壁垒:UI设计师的情感化设计与共情能力成为护城河
  • 公司网站建设 目录dw用设计视图做网站
  • 4-4〔O҉S҉C҉P҉ ◈ 研记〕❘ WEB应用攻击▸本地文件包含漏洞-B
  • Acuvi 旗下PiezoMotor电机:Piezo LEGS 如何解锁纳米级运动控制?
  • 运营专员技能提升培训班推荐:从执行到数据驱动
  • 商城网站建设如何交谈电子产品展示网站模板
  • 银川网站seo邯郸注册公司
  • 网站开发的基本语言网站被拔毛的原因
  • 吉林市网站建设招标在线网站
  • 奈氏准则(奈奎斯特定理Nyquist‘s Theorem)和香农采样定理(Shannon Sampling Theorem)
  • 用sql网站建设基本流程小说网站开发实训报告
  • vps如何创建网站wordpress onthego
  • 东莞做网站哪家最好商城源码开源
  • uniapp生成二维码组件全能组件复制即用
  • 如何安装网站模版seo排名优化课程
  • Git 多人协作(2)
  • 网站建设模式有哪些方面网站精神文件建设专栏
  • 外贸建站服务器怎么选网站备案每年审吗
  • 【不背八股】17.什么是Bert?
  • BMAD框架实践:掌握story-checklist提升用户故事质量
  • 数字化转型:概念性名词浅谈(第五十一讲)
  • 快应用打包rpk同时生成了rpk和rpks是为什么?怎么用?-优雅草卓伊凡
  • 仿站免费申请网站首选百度
  • C++(day2)
  • 网站建设行业论坛哪个做网站公司好
  • 文献解读:南海8GHz蒸发波导信道的大尺度与小尺度衰落特性研究
  • 网站建设中的html页面下载营销策划专业
  • 凡科网站做商城0453信息网免费发布
  • 计算机视觉进阶教学之dlib库(一)
  • 告别局域网束缚:DbGate与cpolar的远程数据库管理实践