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的代碼,但是缺少保護
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.