此版本的list类,很多信息都保存在内部类里面。如果抛开这些内部类,list类里面实质的成员只包括三个:
protected:
_A allocator; //空间配置器
_Nodeptr _Head; //list节点
size_type _Size; //list内元素个数
抛开空间配置器不谈,_Head节点是一个_Node类型的指针
struct _Node;
friend struct _Node;
typedef _POINTER_X(_Node, _A) _Nodeptr;
struct _Node {
_Nodeptr _Next, _Prev;
_Ty _Value;
`
};
_POINTER_X(_Node, _A) 其实就是_Node *的宏
这里还有一个很特殊的类_Acc list里面关于节点指针访问前驱后继和值的操作,全都是由此类的成员函数实现的。这样做的好处就是让程序的可读性变得很好,整体结构变得简单
struct _Acc;
friend struct _Acc;
struct _Acc
{
typedef _Nodeptr & _Nodepref;
typedef _Ty & _Vref;
static _Nodepref _Next(_Nodeptr _P) //后继 引用返回
{
return ((_Nodepref)((*_P)._Next));
}
static _Nodepref _Prev(_Nodeptr _P) //前驱 引用返回
{
return ((_Nodepref)((*_P)._Prev));
}
static _Vref _Value(_Nodeptr _p)//值 引用返回
{
return ((_Vref)((*_p)._Value));
)}
};
我们来看看申请节点函数_Buynode和插入函数的实现,体会一下用_Acc封装这三个函数后,代码结构上优化。
_Nodeptr _Buynode(_Nodeptr _Narg = 0, _Nodeptr _Parg = 0)
{
_Nodeptr _S = (_Nodeptr)malloc(sizeof(_Node) * 1);
_Acc::_Next(_S) = _Narg != 0 ? _Narg : _S;
_Acc::_Prev(_S) = _Parg != 0 ? _Parg : _S;
return _S;
}
在申请节点的同时,可以初始化节点的前驱,后继
void insert(iterator _P, const _Ty &_X = _Ty())
{
_Nodeptr _S = _P.Mynode();
_Acc::_Prev(_S) = _Buynode(_S, _Acc::_Prev(_S));
_S = _Acc::_Prev(_S);
_Acc::_Next(_Acc::_Prev(_S)) = _S;
_Acc::_Value(_S) = _X;
_Size++;
}
我觉得,这样的代码在可读性上,比下面的容易多了,大家可以感受下区别
void insert(iterator _P, const _Ty &_X = _Ty())
{
_Nodeptr _S = _P.Mynode();
S->Prev = _Buynode(_S, S->Prev
_S = S->Prev
S->Prev->Next = _S;
_S->Value= _X;
_Size++;
}
内部类里面还有2个比较特殊的类,就是迭代器iterator和const_iterator
这两个类有什么区别呢?
如果你在使用一个迭代器的时候,你只想遍历元素的_Value域,而不需要改变其值,可是这时候有个问题就是,只在iterator 前面加上const 那么并不能解决这个问题,此时的迭代器变成了常迭代器,只能指向一个节点,而且要在初始化的时候赋值,这样的迭代器并没有什么卵用。所以,在list的内部,定义了一个const_iterator的类,他的作用就是解决上面这个问题的
这两个类的成员只有一个,节点的指针
他的成员函数,就是一堆重载运算符,使其能像普通的指针那样,访问元素,我们拿iterator举例
friend class iterator;
class iterator : public const_iterator {
public:
_Tptr operator->() const
{return (&**this); }
//从有向左,这里第一个*this理解成一个迭代器的实例,对他解引用实际上是调用了其重载运算符*取其节点_Value,然后在取地址返回
iterator& operator++()
{_Ptr = _Acc::_Next(_Ptr);
return (*this); }
iterator operator++(int)
{iterator _Tmp = *this;
++*this;
return (_Tmp); }
//返回++*this 前的*this
};
最后附上自己实现的去掉空间配置器的代码
#ifndef _LIST_H_
#define _LIST_H_
template <class _Ty>
class mylist
{
private:
struct _Node;
friend struct _Node;
typedef _Node * _Nodeptr;
struct _Node
{
_Nodeptr _Prev, _Next;
_Ty _Value;
};
struct _Acc;
friend struct _Acc;
struct _Acc
{
typedef _Nodeptr & _Nodepref;
typedef _Ty & _Vref;
static _Nodepref _Next(_Nodeptr _P)
{
return ((_Nodepref)((*_P)._Next));
}
static _Nodepref _Prev(_Nodeptr _P)
{
return ((_Nodepref)((*_P)._Prev));
}
static _Vref _Value(_Nodeptr _p)
{
return ((_Vref)((*_p)._Value));
}
};
public:
typedef mylist<_Ty> _Myt;
typedef unsigned int size_type;
//typedef _PDFT difference_type;
typedef _Ty * pointer;
typedef const _Ty *const_pointer;
typedef _Ty & reference;
typedef const _Ty & const_reference;
typedef _Ty value_type;
class iterator;
friend class iterator;
class iterator
{
public:
iterator()
{}
iterator(_Nodeptr _P) :_Ptr(_P)
{}
iterator(iterator &_X) :_Ptr(_X._Ptr)
{}
reference operator*()
{
return (_Acc::_Value(_Ptr));
}
pointer operator->()
{
return &**this;//
}
iterator& operator++()
{
_Ptr = _Acc::_Next(_Ptr);
return *this;//对象
}
iterator operator++(int)
{
iterator Tmp = *this;
++*this;
return Tmp;
}
iterator& operator--()
{
_Ptr = _Acc::_Prev(_Ptr);
return *this;//对象
}
iterator operator--(int)
{
iterator Tmp = *this;
--*this;
return Tmp;
}
bool operator==(iterator &_X)
{
return _Ptr == _X._Ptr;
}
bool operator!=(iterator &_X)
{
return _Ptr != _X._Ptr;
}
_Nodeptr Mynode()const
{
return _Ptr;
}
protected:
_Nodeptr _Ptr;
};
typedef iterator _It;
public:
mylist() :_Head(_Buynode()),_Size(0)
{}
mylist(size_type _N, const _Ty &_X=_Ty()) :_Head(_Buynode()), _Size(0)
{
insert(end(), _N, _X);
}
mylist(_Myt& _X) :_Head(_Buynode()), _Size(0) //
{
insert(end(), _X.begin(), _X.end());
}
mylist(_It _F, _It _L) :_Head(_Buynode()), _Size(0)
{
insert(end(), _F, _L);
}
mylist(const _Ty *_F, const _Ty *_L) :_Head(_Buynode()), _Size(0)
{
insert(end(), _F, _L);
}
~mylist()
{
erase(begin(), end());
_Freenode(_Head);
_Head = 0; //防止野指针
_Size = 0;
}
iterator begin()
{
return (iterator(_Acc::_Next(_Head)));
}
iterator end()
{
return iterator(_Head);
}
size_type size()
{
return _Size
};
bool empty()
{
return _Size == 0;
}
void clear()
{
erase(begin(), end());
}
void push_back(const _Ty &_X = _Ty())
{
insert(end(),_X);
}
void push_front(const _Ty &_X = _Ty())
{
insert(begin(),_X);
}
void pop_front()
{
erase(begin());
}
void pop_back()
{
//erase(end())
erase(--end());//
}
iterator erase(iterator _P)
{
_Nodeptr _S = (_P++).Mynode();
_Acc::_Next(_Acc::_Prev(_S)) = _Acc::_Next(_S);
_Acc::_Prev(_Acc::_Next(_S)) = _Acc::_Prev(_S);
_Freenode(_S);
--_Size;
return _P;
}
void erase(iterator _F, iterator _L)
{
/*for (; _F != _L; _F++)
{
erase(_F);
}*/
while (_F != _L)
{
erase(_F++);
}
}
void insert(iterator _P, const _Ty &_X = _Ty())
{
_Nodeptr _S = _P.Mynode();
_Acc::_Prev(_S) = _Buynode(_S, _Acc::_Prev(_S));
_S = _Acc::_Prev(_S);
_Acc::_Next(_Acc::_Prev(_S)) = _S;
_Acc::_Value(_S) = _X;
_Size++;
}
void insert(iterator _P, size_type _N,const _Ty&_X = _X()) //在_P 前插入_N个_X
{
for (; _N; _N--)
{
insert(_P, _X);
}
}
void insert(iterator _P, _It _F, _It _L)
{
for (; _F != _L;_F++)
{
insert(_P, *_F);
}
}
void insert(iterator _P, const _Ty *_F, const _Ty *_L)
{
for(; _F != _L;_F++)
{
insert(_P, *_F);
}
}
void assign(size_type _N, const _Ty& _X)
{
erase(begin(), end());
insert(end(), _N, _X);
}
void assign(iterator _F, iterator _L)
{
erase(begin(), end());
insert(end(), _F, _L);
}
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 != _L && _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)
{
int _N = 0;
_Distance(_F, _L, _N);
_Size += _N;
_X._Size -= _N;
}
_Splice(_P, _X, _F, _L);
}
}
void swap(_Myt& _X)
{
iterator _L = begin();
splice(_L, _X);
_X.splice(_X.begin(), *this, _L, end());
}
friend void swap(_Myt& _X, _Myt& _Y)
{
_X.swap(_Y);
}
void remove(const _Ty& _V)
{
iterator _F = begin();
while (_F != end())
{
if (*_F == _V)
erase(_F++);
else
++_F;
}
}
void unique()
{
iterator _F = begin();
iterator _M ;
for (_M = _F; ++_M != end(); _M = _F)
{
if (*_F == *_M)
erase(_M);
else
_F = _M;
}
}
void reverse()
{
if (_Size >= 2)
{
iterator _F = ++begin();
iterator _M;
for (; _F != end();)
{
_M = _F;
splice(begin(), *this, _M, ++_F);
}
}
}
void merge(_Myt& _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 _M = _F2++;
splice(_F1, _X, _M, _F2);
}
else
_F1++;
}
if (_F2 != _L2)
splice(_L1, _X, _F2, _L2);
_Size += _X._Size;
_X._Size = 0;
}
}
protected:
_Nodeptr _Buynode(_Nodeptr _Narg = 0, _Nodeptr _Parg = 0)
{
_Nodeptr _S = (_Nodeptr)malloc(sizeof(_Node) * 1);
_Acc::_Next(_S) = _Narg != 0 ? _Narg : _S;
_Acc::_Prev(_S) = _Parg != 0 ? _Parg : _S;
return _S;
}
void _Freenode(_Nodeptr _P)
{
free(_P);
}
void _Splice(iterator _P, _Myt& _X, iterator _F, iterator _L)
{
insert(_P, _F, _L);
_X.erase(_F, _L);
}
void _Distance(iterator _F, iterator _L, int &_N)
{
while (_F != _L)
{
_N++;
_F++;
}
}
_Nodeptr _Head;
size_type _Size;
};
#endif
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/a781558066/article/details/46844625