【C++/STL】list的实现(采用空间配置器和迭代器)

在list库函数的编译中仍然有很多问题,在源代码的编译中有些内容尚未搞懂,在后期的学习中会进行更加深入的学习,希望大家可以对我的问题提出建议和批评,谢谢大家~

具体的代码如下:

#include <iostream>
using namespace std;
//采用迭代器和空间配置器所实现的双向链表的基本功能
template<class _Ty,class _A = allocator<_Ty> >
//定义模板类
class list
//list类
{
public:
	typedef size_t size_type;
	//类型重定义
protected:
	struct _Node;
	//结构体_Node
	friend struct _Node;
	//友元
	typedef _Node* _Nodeptr;
	//类型重定义
	struct _Node
	//结构体定义
	{
		_Nodeptr _Next,_Prev;
		_Ty _Value;
	};
protected:
	_A allocator;
	_Nodeptr _Head;
	size_type _Size;
public:
	typedef list<_Ty,_A> _Myt;
	typedef _A allocator_type;
	//该类型是模板参数A的同义词
	typedef size_t size_type;
	//正整数类型
	typedef ptrdiff_t difference_type;
	//整数类型
	typedef _Ty* pointer;
	//指向_Ty的指针
	typedef const _Ty* const_pointer;
	//指向_Ty的常量指针
	typedef _Ty& reference;
	//_Ty的引用
	typedef const _Ty& const_reference;
	//_Ty的常量引用
	typedef _Ty value_type;
	//对象类型_Ty
	class iterator;
	//访问list的迭代器
	class const_iterator;
	//访问list的常量迭代器
	friend class const_iterator;
	//友元
	class const_iterator : public _Bidit<_Ty, difference_type>
	//继承
	{
	public:
		//共有成员
		_Nodeptr _Mynode() const
		//指向当前结点
		{
			return (_Ptr);
		}
		const_iterator()
		//默认构造函数
		{}
		const_iterator(_Nodeptr _P):_Ptr(_P)
		//参数为指针的构造函数
		{}
		const_iterator(const iterator& _X):_Ptr(_X._Ptr)
		//参数为访问list的常量迭代器的构造函数
		{}
		const_reference operator*() const
		//获取当前_Ty的常量的值
		{
			return _Ptr->_Value;
		}
		const_pointer operator->() const
		//?
		{
			return (&**this);
		}
		const_iterator& operator++()
		//前置++的引用
		{
			_Ptr = _Ptr->_Next;
			return (*this);
		}
		const_iterator operator++(int)
		//后置++的引用
		{
			const_iterator _Tmp = *this;
			++*this;
			return (_Tmp);
		}
		const_iterator& operator--()
		//前置--的引用
		{
			_Ptr = _Ptr->_Prev;
			return (*this);
		}
		const_iterator operator--(int)
		//后置--的引用
		{
			const_iterator _Tmp = *this;
			--*this;
			return (_Tmp);
		}
		bool operator==(const const_iterator& _X) const
		//判断是否相等
		{
			return (_Ptr == _X._Ptr);
		}
		bool operator!=(const const_iterator& _X) const
		//判断是否不等
		{
			return (!(*this == _X));
		}
	protected:
	    //保护成员
		_Nodeptr _Ptr;
	};
	friend class iterator;
    //友元
	class iterator : public const_iterator
	//继承
	{
	public:
		iterator()
		//默认构造函数
		{}
		iterator(_Nodeptr _P): const_iterator(_P)
		//参数为指针的构造函数
		{}
		reference operator*() const
		//获取当前_Ty的值
		{
			return _Ptr->_Value;
		}
		_Ty* operator->() const
		//?
		{
			return (&**this);
		}
		iterator& operator++()
		//前置++的引用
		{
			_Ptr = _Ptr->_Next;
			return (*this);
		}
		iterator operator++(int)
		//后置++的引用
		{
			iterator _Tmp = *this;
			++*this;
			return (_Tmp);
		}
		iterator& operator--()
		//前置--的引用
		{
			_Ptr = _Ptr->_Prev;
			return (*this);
		}
		iterator operator--(int)
		//后置--的引用
		{
			iterator _Tmp = *this;
			--*this;
			return (_Tmp);
		}
		bool operator==(const iterator& _X) const
		//判断是否相等
		{
			return (_Ptr == _X._Ptr);
		}
		bool operator!=(const iterator& _X) const
		//判断是否不等
		{
			return (!(*this == _X));
		}
	};
public:
	_Nodeptr _Buynode(_Nodeptr _Narg = 0, _Nodeptr _Parg = 0)
	//购买结点
	{
		_Nodeptr _S = (_Nodeptr)allocator._Charalloc(   //开辟空间
			1 * sizeof (_Node));
		_S->_Next = _Narg != 0 ? _Narg : _S;;
		_S->_Prev = _Parg != 0 ? _Parg : _S;
		return (_S);
	}
	void _Freenode(_Nodeptr _S)
	//释放空间
	{
		allocator.deallocate(_S, 1);
	}
	void _Splice(iterator _P, _Myt& _X, iterator _F, iterator _L)
	//拼接
	{
		if (allocator == _X.allocator)                 //将两个拼接到一起,_X清空
		{
			(_L._Mynode())->_Prev->_Next = _P._Mynode();
			(_F._Mynode())->_Prev->_Next = _L._Mynode();
			(_P._Mynode())->_Prev->_Next = _F._Mynode();
			_Nodeptr _S = (_P._Mynode())->_Prev;
			(_P._Mynode())->_Prev =(_L._Mynode())->_Prev;
			(_L._Mynode())->_Prev =(_F._Mynode())->_Prev;
			(_F._Mynode())->_Prev = _S;
		}
		else                                          //将_X中的链表数值添加到_P中,_X清空
		{
			insert(_P, _F, _L);
			_X.erase(_F, _L);
		}
	}
	void _Xran() const
	//抛出异常
	{
		_THROW(out_of_range, "invalid list<T> subscript");
	}
public:
	size_type size() const
	//长度
	{
		return (_Size);
	}
	bool empty() const
	//判空
	{
		return (size() == 0);
	}
	_A get_allocator() const
	//返回空间配置器
	{
		return (allocator);
	}
	void resize(size_type _N, _Ty _X = _Ty())
	//重新定义链表长度
	{
		if (size() < _N)
		{
			insert(end(), _N - size(), _X);
		}
		else
		{
			while (_N < size())
			{
				pop_back();
			}
		}
	}
	size_type max_size() const
	//返回链表最大可能长度
	{
		return (allocator.max_size());
	}
	reference front()
	//返回第一个元素的引用
	{
		return (*begin());
	}
	const_reference front() const
	//返回第一个元素的常量引用
	{
		return (*begin());
	}
	reference back()
	//返回最后一元素的引用
	{
		return (*(--end()));
	}
	const_reference back() const
	//返回最后一元素的常量引用
	{
		return (*(--end()));
	}
	_Myt& operator=(const _Myt& _X)
	//运算符构造函数
	{
		if (this != &_X)
		{
			iterator _F1 = begin();
			iterator _L1 = end();
			const_iterator _F2 = _X.begin();
			const_iterator _L2 = _X.end();
			for (; _F1 != _L1 && _F2 != _L2; ++_F1, ++_F2)
			{
				*_F1 = *_F2;
			}
			erase(_F1, _L1);
			insert(_L1, _F2, _L2);
		}
		return (*this);
	}
public:
	explicit list():_Head(_Buynode()), _Size(0)
	//空链表
	{}
	explicit list(const _Ty& _V):_Head(_Buynode()), _Size(0)
	//建一个含_V个默认值是0的元素的链表
	{
		insert(begin(),_V,0);
	}
    explicit list(size_type _N, const _Ty& _V):_Head(_Buynode()), _Size(0)
	//建一个含_V个元素的链表,值都是_N
	{
		insert(begin(),_N, _V);
	}
	list(const _Myt& _X): _Head(_Buynode()), _Size(0)
	//建一个_X的copy链表
	{
		insert(begin(), _X.begin(), _X.end());
	}
	list(const _Ty *_F, const _Ty *_L): _Head(_Buynode()), _Size(0)
	//一个区域的元素[_First, _Last)。
	{
		insert(begin(), _F, _L);
	}
	typedef const_iterator _It;
	list(_It _F, _It _L):_Head(_Buynode()), _Size(0)
	//常量迭代器
	{
		insert(begin(), _F, _L);
	}
	iterator begin()
	//迭代器第一个节点
	{
		return iterator(_Head->_Next);
	}
	const_iterator begin() const
	//常量迭代器第一个节点
	{
		return (const_iterator(_Head->_Next));
	}
	iterator end()
	//返回最后一个元素的下一位置的指针
	{
		return iterator(_Head);
	}
	const_iterator end() const
	//返回最后一个元素的下一位置的指针
	{
		return (const_iterator(_Head));
	}
	iterator insert(iterator _P,const _Ty& _X)
	//在_P之前插入结点
	{
		_Nodeptr _S = _P._Mynode();
		_S->_Prev = _Buynode(_S,_S->_Prev);
		_S = _S->_Prev;
		_S->_Prev->_Next = _S;
		_S->_Value = _X;
		++_Size;
		return (iterator(_S));
	}
	void insert(iterator _P,size_type _M, const _Ty& _X)
	//在_P之前插入_M个_X结点
	{
		for(;0 < _M;--_M)
		{
			insert(_P,_X);
		}
	}
	void insert(iterator _P, const _Ty *_F, const _Ty *_L)
	//在_P之前插入_F到_L的结点
	{
		for (; _F != _L; ++_F)
		{
			insert(_P, *_F);
		}
	}
	typedef const_iterator _It;
	void insert(iterator _P, _It _F, _It _L)
	//在_P之前插入迭代器_F到_L的结点
	{
		for (; _F != _L; ++_F)
		{
			insert(_P, *_F);
		}
	}
	void push_front(const _Ty& _X)
	//增加一元素到链表头
	{
		insert(begin(), _X);
	}
	void pop_front()
	//删除链表头的一元素
	{
		erase(begin());
	}
	void push_back(const _Ty& _X)
	//增加一元素到链表尾
	{
		insert(end(), _X);
	}
	void pop_back()
	//删除链表尾的一个元素
	{
		erase(--end());
	}
	void assign(size_type _N, const _Ty& _X)
	//分配值
	{
		erase(begin(),end());
		insert(begin(),_N, _X);
	}
	iterator erase(iterator _P)
	//删除_P元素
	{
		_Nodeptr _S = (_P++)._Mynode();
		_S->_Prev->_Next = _S->_Next;
		_S->_Next->_Prev = _S->_Prev;
		_Freenode(_S);
		--_Size;
		return (_P);
	}
	iterator erase(iterator _F, iterator _L)
	//删除_F到_L区域的元素
	{
		while (_F != _L)
		{
			erase(_F++);
		}
		return (_F);
	}
	void clear()
	//删除所有元素
	{
		erase(begin(),end());
	}
	void show()
	//STL源码中不存在的函数,自己加的,为了使得测试更方便
	{
		_Nodeptr _P = _Head->_Next;
		while(_P != _Head)
		{
			cout<<_P->_Value<<"-->";
			_P = _P->_Next;
		}
		cout<<"Over"<<endl;
	}
	~list()
	//析构函数
	{
		erase(begin(),end());
		_Freenode(_Head);
		_Head = 0, _Size = 0;
	}
public:
	void swap(_Myt& _X)
	//交换两个链表
	{
		if (allocator == _X.allocator)
		//若空间配置器相同,则只需交换头结点和大小
		{
			std::swap(_Head, _X._Head);
			std::swap(_Size, _X._Size);
		}
		else
		//否则将链表分别拼接到对方空间中
		{
			iterator _P = begin();
			splice(_P, _X);
			_X.splice(_X.begin(), *this, _P, end());
		}
	}
	friend void swap(_Myt& _X, _Myt& _Y)
	//交换两个链表
	{
		_X.swap(_Y);
	}
	void splice(iterator _P, _Myt& _X)
	//对两个链表进行拼接
	{
		if (!_X.empty())
		{
			_Splice(_P, _X, _X.begin(), _X.end());
			_Size += _X._Size;
			_X._Size = 0;
		}
	}
	void splice(iterator _P, _Myt& _X, iterator _F)
	//对两个链表进行拼接
	{
		iterator _L = _F;
		if (_P != _F && _P != ++_L)
		{
			_Splice(_P, _X, _F, _L);
			++_Size;
			--_X._Size;
		}
	}
	void splice(iterator _P, _Myt& _X, iterator _F, iterator _L)
	//对两个链表进行拼接
	{
		if (_F != _L)
		{
			if (&_X != this)
			{
				difference_type _N = 0;
				_Distance(_F, _L, _N);
				_Size += _N;
				_X._Size -= _N;
			}
			_Splice(_P, _X, _F, _L);
		}
	}
	void remove(const _Ty& _V)
	//从链表中删除所有值为_V的元素
	{
		iterator _L = end();
		for (iterator _F = begin(); _F != _L; )
		{
			if (*_F == _V)
			{
				erase(_F++);
			}
			else
			{
				++_F;
			}
		}
	}
	void unique()
	//删除所有重复的元素,以建立一个具有唯一元素值的链表,
	//即链表中不会有重复元素
	{
		iterator _F = begin(), _L = end();
		if (_F != _L)
		{
			for (iterator _M = _F; ++_M != _L; _M = _F)
			{
				if (*_F == *_M)
				{
					erase(_M);
				}
				else
				{
					_F = _M;
				}
			}
		}
	}
	void merge(_Myt& _X)
	//把当前链表*this和x合并,合并后x为空,
	//把x中的元素插入到当前链表中,不允许两个链表相同
	{
		if (&_X != this)
		{
			iterator _F1 = begin(), _L1 = end();
			iterator _F2 = _X.begin(), _L2 = _X.end();
			while (_F1 != _L1 && _F2 != _L2)
			{
				if (*_F2 < *_F1)
				{
					iterator _Mid2 = _F2;
					_Splice(_F1, _X, _F2, ++_Mid2);
					_F2 = _Mid2;
				}
				else
				{
					++_F1;
				}
			}
			if (_F2 != _L2)
			{
				_Splice(_L1, _X, _F2, _L2);
			}
			_Size += _X._Size;
			_X._Size = 0;
		}
	}
	void reverse()
	//反转链表中的元素排序
	{
		if (2 <= size())
		{
			iterator _L = end();
			for (iterator _F = ++begin(); _F != _L; )
			{
				iterator _M = _F;
				_Splice(begin(), *this, _M, ++_F);
			}
		}
	}
	void sort()
	//根据默认条件对链表进行排序?
	{
		if (2 <= size())
		{
			const size_t _MAXN = 15;
			_Myt _X, _A[_MAXN + 1];
			size_t _N = 0;
			while (!empty())
			{
				_X.splice(_X.begin(), *this, begin());
				size_t _I;
				for (_I = 0; _I < _N && !_A[_I].empty(); ++_I)
				{
					_A[_I].merge(_X);
					_A[_I].swap(_X);
				}
				if (_I == _MAXN)
				{
					_A[_I].merge(_X);
				}
				else
				{
					_A[_I].swap(_X);
					if (_I == _N)
					{
						++_N;
					}
				}
			}
			while (0 < _N)
			{
				merge(_A[--_N]);
			}
		}
	}
};
template<class _Ty, class _A> inline
//模板类判断是否相等
bool operator==(const list<_Ty, _A>& _X,
				const list<_Ty, _A>& _Y)
{
	return (_X.size() == _Y.size()
		 && equal(_X.begin(), _X.end(), _Y.begin()));
}
template<class _Ty, class _A> inline
//模板类判断是否不等
bool operator!=(const list<_Ty, _A>& _X,
				const list<_Ty, _A>& _Y)
{
	return (!(_X == _Y));
}
template<class _Ty, class _A> inline
//模板类比较链表的大小
bool operator<(const list<_Ty, _A>& _X,
			   const list<_Ty, _A>& _Y)
{
	return (lexicographical_compare(_X.begin(), _X.end(),
		 _Y.begin(), _Y.end()));
}
template<class _Ty, class _A> inline
//模板类比较链表的大小_Y < _X
bool operator>(const list<_Ty, _A>& _X,
			   const list<_Ty, _A>& _Y)
{
	return (_Y < _X);
}
template<class _Ty, class _A> inline
//模板类比较链表的大小!(_Y < _X)
bool operator<=(const list<_Ty, _A>& _X,
				const list<_Ty, _A>& _Y)
{
	return (!(_Y < _X));
}
template<class _Ty, class _A> inline
//模板类比较链表的大小!(_X < _Y)
bool operator>=(const list<_Ty, _A>& _X,
				const list<_Ty, _A>& _Y)
{
	return (!(_X < _Y));
}

void main()
{
	list<int> c0;                         //空链表
	list<int> c1(3);                      //建一个含三个默认值是0的元素的链表
	list<int> c2(c1);                     //建一个c1的copy链表
	list<int> c3(c1.begin(),c1.end());    //含c1一个区域的元素[_First, _Last)。
	int ar[5] = {12,23,34,45,56};
	list<int> itlist(ar,ar+5);            //用数组赋值
	list<int> mylist(3,2);                //建一个含三个元素的链表,值都是2
	mylist.show();

	list<int> youlist(3,3);
	youlist.show();

	swap(mylist, youlist);                //交换两个链表
	mylist.show();
	youlist.show();

	mylist.swap(youlist);
	mylist.show();
	youlist.show();

	list<int>::iterator i1 = itlist.begin();
	itlist.splice(i1,mylist);              //对两个链表进行结合
	itlist.show();

	itlist.remove(23);
	itlist.show();

	itlist.unique();
	itlist.show();

	itlist.merge(mylist);
	itlist.show();
	mylist.show();

	itlist.reverse();
	itlist.show();

	itlist.sort();
	itlist.show();

	cout<<operator<(itlist,mylist)<<endl;
	cout<<operator>(itlist,mylist)<<endl;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-17 13:33:28

【C++/STL】list的实现(采用空间配置器和迭代器)的相关文章

《STL源码剖析》空间配置器

空间配置器(allocator) 空间配置器按我的理解就是C++ STL进行内存管理的组件(包括内存的申请和释放):当然,不只是内存,还可以向硬盘申请空间: 我主要看了内存的配置与释放(这里"配置"就应该是"申请"的意思).STL对此设计的哲学主要包括以下四个方面: 1.向系统堆空间申请内存空间 2.考虑了多线程的情况下的申请: 3.考虑内存不足的应变措施: 4.考虑过多"小型区块"的内存碎片的问题: C++ 申请的基本动作是::operator

STL学习笔记--2、空间配置器 allocator

2.1标准接口 allocator::value_type allocator::pointer allocator::const_pointer allocator::reference allocator::const_reference allocator::size_type allocator::difference_type allocator::rebind allocator::allocator()//默认构造函数 allocator::allocator(const allo

STL(六)之空间配置器

在SGI STL版本的内存管理中,使用这样一种方式来分配内存:内存分配+对象初始化.首先是分配内存,其次是根据对象的类型(是否为POD[Plain of Data])来使用最有效的方式来初始化对象.回收内存也是用同样的方式:析构对象+回收内存,根据对象是否为POD类型,确定最有效的析构方式.SGI STL使用双层级配置器,第一级配置器直接使用malloc()和free(),第二级根据如下策略:当配置区块>128 Bytes时,视之为“足够大”,调用一级配置器,否则视之为过小,调用二级配置器. 一

STL源码剖析:空间配置器

看完自己重写了一下,不知道的又看了一遍,里面没有考虑多线程的问题,主要是想实现以下内存池. Mempool.h #ifndef MEMPOOL_H_ #define MEMPOOL_H_ #include <cstddef> #include <new> #include <cstdlib> namespace flysnow { enum {STEP_ = 8}; enum {MAX_BYTES_ = 128}; enum {FREELIST_NUM_ = MAX_B

【C++/STL】list的实现(没有采用迭代器和空间配置器所实现的双向链表的基本功能)

<span style="font-size:18px;">#include <iostream> using namespace std; //没有采用迭代器和空间配置器所实现的双向链表的基本功能 template<class _Ty> //定义模板类 class list //list类 { public: typedef size_t size_type; //类型重定义 protected: struct _Node; //结构体_Node

STL源码剖析 — 空间配置器(allocator)

前言 以STL的实现角度而言,第一个需要介绍的就是空间配置器,因为整个STL的操作对象都存放在容器之中. 你完全可以实现一个直接向硬件存取空间的allocator. 下面介绍的是SGI STL提供的配置器,配置的对象,是内存.(以下内容来自<STL源码剖析>) 空间配置器的标准接口 根据STL的规范,allocator的必要接口 各种typedef 1 allocator::value_type 2 allocator::pointer 3 allocator::const_pointer 4

STL源码剖析--空间配置器

STL的设计非常巧妙,组件间互取短长,形成了一个世界,这是这个世界里的组件: 1. containers(容器):所谓容器,是指存放数据的地方,将数据以一定的方法组织存放.根据不同的组织方式,可以把容器分为顺序容器,如vector.deque.list,关联容器,如set.map.Container是一种class template. 2. algorithm(算法):各种常用不常用的算法如sort.copy.search等等.algorithm是一种function template. 3.

STL——空间配置器(SGI-STL)

一. 空间配置器标准接口 参见<STL源码剖析>第二章-2.1. 二.具备次配置力的SGI空间配置器 SGI STL的配置器与众不同,也与标准规范不同,其名称是alloc而非allocator,而且不接受任何参数(虽然SGI也定义有一个符合部分标准.名为sllocator的配置器,但SGI自己从未用过它,也不建议使用,主要因为效率不佳).这并不会带来什么困扰:我们通常很少需要自行指定配置器名称,而SGI STL的每一个容器都已经指定其缺省的空间配置器为alloc. // 在程序中要明白采用SG

STL源码剖析(1):空间配置器

STL所有的操作对象(所有的数值)都存放在容器之内,容器需要分配空间以存放数据.为什么不说allocator是内存配置器而是空间配置器,因为空间不仅是内存,空间也可以是磁盘或其它辅助储存媒体.这里我们主要讨论内存配置. SGI STL每个容器缺省的空间配置器为alloc,如vector: template<class T, class Alloc = alloc> class vector{--} 一般而言,C++的内存配置和释放操作如下: class Object{--}; Object*