template <typename Object> //这里的实现是不改变data的
class List
{
private:
struct Node //struct是public的,这里把它作为private,也没毛病,就是Node里的东西List类都能用
{
Object data;
Node *prev;
Node *next;
Node(const Object &d = Object(), Node *p = NULL, Node *n = NULL) :data(d), prev(p), next(n){} //这种构造办法很好,不容易出错,建议用
};
public:
class const_iterator
{
public:
const_iterator() :current(NULL)
{}
const Object & operator* () const //*的运算符重载,取数据的,protect里有retrieve
{
return retrieve();
}
const_iterator & operator++() //前缀的++(++i),使用空参数列表。前缀比后缀快,所以编程的时候尽量用++i......
{
current = current->next;
return *this;
}
const_iterator operator++ (int) //后缀的++(i++),给后缀指定一个匿名的int参数,int参数是不会使用的,只是一个不同的标识
{
const_ierator old = *this;
++(*this);
return old;
}
bool operator== (const const_iterator &rhs) const
{
return current == rhs.current;
}
bool operator!=(const const_iterator &rhs) const
{
return !(*this == rhs);
}
protected:
Node *current; //current是指向Node的指针,不能是私有的,否则iterator将不能访问这个指针。protect允许继承的类具有访问这些成员的权限,但是不允许其他的类访问
Object & retrieve() const
{
return current->data;
}
const_iterator(Node *p) :current(p){} //不希望所有的类都能访问这个const_iterator的构造函数,但是希望iterator可以访问,所以放到了protect里
friend class List < Object > ;
};
class iterator:public const_iterator //两个迭代器类型,用了继承。
{
public:
iterator(){}
Object & operator*() //*可以修改的重载
{
return retrieve();
}
const Object & operator* () const //*只能访问的重载,不能改变,简单使用了与const_iterator完全相同的实现
{
return const_iterator::operator*(); //在iterator中,修改函数必须显示实现,因为不这样的话原始的实现就会被新加的修改函数隐藏
}
iterator & operator++ () //这里operator==和operator!=不需要改变,但是++要改变,因为类型改变了,这个新的实现隐藏了const_iterator的原始实现
{
current = current->next;
return *this;
}
iterator operator++ (int)
{
iterator old = *this;
++(*this);
return old;
}
protected:
iterator(Node *p) :const_iterator(p)
{}
friend class List < Object > ;
};
public:
List() //喜闻乐见,List的构造函数,拷贝构造函数,析构函数,=的运算符重载
{
init();
}
List(const List & rhs)
{
init();
*this = ths;
}
~List()
{
clear();
delete head;
delete tail;
}
const List & operator=(const List &rhs)
{
if (this == &rhs)
return *this;
clear();
for (const_iterator itr = rhs.begin(); itr != rhs.end(); ++itr)
push_back(*itr);
return *this;
}
//一些常用小函数
iterator begin() //迭代器的取begin和end,这里又一次说明,begin是真的begin,end是最后一个的后一个
{
return iterator(head->next); //这个iterator()是迭代器iterator的构造函数,return构造函数,是因为构造函数临时构造了一个对象,然后临时返回这个对象,所以出现了这里的return
}
const_iterator begin() const
{
return const_iterator(head->next);
}
iterator end()
{
return iterator(tail);
}
const_iterator end() const
{
return const_iterator(tail);
}
int size() const //取大小
{
return theSize;
}
bool empty() const //判空
{
return size() == 0;
}
void clear() //清空,调用pop_front让clear不染指节点空间的回收
{
while (!empty())
pop_front();
}
Object & front() //取首元素,这个*iterator在迭代器的类里,*是重载过的,意思就是取data
{
return *begin();
}
const Object & front() const //每个有两种,带const的是不能修改的,不带const的是能修改的
{
return *begin();
}
Object & back() //取尾元素
{
return *--end();
}
const Object & back() const
{
return *--end();
}
void push_front(const Object &x)
{
insert(end(), x);
}
void push_back(const Object &x)
{
insert(end(), x);
}
void pop_front()
{
erase(begin());
}
void pop_back()
{
erase(--end()); //这样也是避免结点空间回收的,只有几个是涉及到节点空间的
}
iterator insert(iterator itr, const Object &x)
{
Node *p = itr.current; //让*p是指向当前结点的指针
theSize++;
return iterator(p->prev = p->prev->next = new Node(x, p->prev, p));
/*这个拆开看,最后iterator()里的东西,就是这个new的Node,数据是x的这个。双向链表的插入节点
Node *newNode = new Node(x,p->prev,p);
p->prev->next=newNode;
p->prev=newNode;
*/
}
iterator erase(iterator itr) //删除一个的
{
Node *p = itr.current;
iterator retVal(p->next); //erase返回指向删除结点的下一个结点的指针,这行的作用
p->prev->next = p->next;
p->next->prev = p->prev;
delete p;
theSize--;
return retVal;
}
iterator erase(iterator start, iterator end) //这个是都删除的
{
for (iterator itr = from; itr != to;) //这个感觉给错了,from和to应该用start和end
itr = erase(itr);
return to;
}
private:
int theSize;
Node *head;
Node *tail;
void init()
{
theSize = 0;
head = new Node;
tail = new Node;
head->next = tail;
tail->prev = head;
}
};
链表List的代码,但是缺少保护
最新推荐文章于 2022-04-06 10:59:52 发布