马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 andalousie 于 2014-1-26 10:08 编辑
代码源自《C++ in Action》的练习题,书中解答只写出了主要代码。这里提供完整代码。
这个程序是通过序列器访问链表以及通过解链序列器删除链表元素的实例。
list.h#if !defined (LIST_H)
#define LIST_H
class Link
{
public:
Link (Link* pNext, int id)
: _pNext (pNext), _id (id) {}
Link * Next () const { return _pNext; }
void SetNext (Link* pNext) { _pNext = pNext; }
int Id () const { return _id; }
private:
Link * _pNext;
int _id;
};
class List
{
friend class UnlinkSeq;
public:
List (): _pHead (0) {}
~List ();
void Add ( int id );
Link const * GetHead () const { return _pHead; }
protected:
Link* _pHead;
};
// List sequencer
// Usage:
// for (ListSeq seq (list);
// !seq.AtEnd ();
// seq.Advance ())
// {
// int id = seq.GetId ();
// ...
// }
class ListSeq
{
public:
ListSeq (List const & list)
: _pLink (list.GetHead ()) {}
bool AtEnd () const { return _pLink == 0; }
void Advance () { _pLink = _pLink->Next (); }
int GetId () const { return _pLink->Id (); }
private:
Link const * _pLink; // current link
};
class UnlinkSeq
{
public:
UnlinkSeq(List & list)
: _list(list),
_cur(list._pHead),
_prev(0)
{}
bool AtEnd() const { return _cur == 0; }
void Advance()
{
_prev = _cur;
_cur = _cur->Next();
}
int Id() const { return _cur->Id(); }
void Unlink();
private:
List & _list;
Link * _cur;
Link * _prev;
};
#endif
list.cpp#include "List.h"
#include <iostream>
#include <cassert>
List::~List ()
{
// free the list
while ( _pHead != 0 )
{
Link* pLink = _pHead;
_pHead = _pHead->Next(); // unlink pLink
delete pLink;
}
}
void List::Add ( int id )
{
// add in front of the list
Link * pLink = new Link (_pHead, id);
_pHead = pLink;
}
void UnlinkSeq::Unlink()
{
assert(_cur != 0);
if(_prev == 0)
{
assert(_cur == _list._pHead);
_list._pHead = _cur->Next();
}
else
{
_prev->SetNext(_cur->Next());
}
delete _cur;
_cur = 0;
}
int main ()
{
List list;
list.Add (1);
list.Add (2);
list.Add (5);
list.Add (3);
std::cout << "List contents:\n";
for (Link const * pLink = list.GetHead();
pLink != 0;
pLink = pLink->Next ())
{
std::cout << pLink->Id() << " ";
}
std::cout << std::endl;
//Another method using sequencer
std::cout << "List sequencer:\n";
for (ListSeq seq (list);
!seq.AtEnd ();
seq.Advance ())
{
std::cout << seq.GetId () << " ";
}
std::cout << std::endl;
//using unlink sequencer
//to delete an element
UnlinkSeq useq (list);
while (useq.Id () != 5)
useq.Advance();
if(!useq.AtEnd()) useq.Unlink();
for (ListSeq seq (list);
!seq.AtEnd ();
seq.Advance ())
{
std::cout << seq.GetId () << " ";
}
return 0;
}
|