线性表(智能指针实现)

#ifndef LIST_H
#define LIST_H
#include
using namespace std;
//异常类,当查询的索引发生错误的时候抛出这个异常
class BadIndex :public exception
{
public:
virtual const char* what() const throw()
{
return "你输入的索引位置错误";
}
};
【线性表(智能指针实现)】template
class List;
//计数类指针,用来在list中使用。没有定义复制控制,默认的就符合要求
template
class ListRep
{
private:
P *m_rep;
int m_useCount;
friend class List;
ListRep(P* rep);
~ListRep();
//将使用计数增加一
void increment();
//将使用计数减少一,当使用计数减小到0的时候删除指针所指向的资源
//不能删除对象本身,那样会出错
void decrement();
//将一个指针所指向的资源复制到另一个指针中
//这主要是在list中进行插入,删除以及向其中添加数据的时候使用
//当进行这些操作的时候不能改变指针多指向的单元因为这个时候不止
//一个指针指向它,所以要复制单独的一份进行操作
void copy(const ListRep *lr, int size);
};
template
void ListRep::copy(const ListRep *lr, int size)//不会对目标区间的大小做检查
{
for (int i = 0; i != size; ++i)
(this->m_rep)[i] = (lr->m_rep)[i];
}
template
ListRep::ListRep(P *rep):m_rep(rep), m_useCount(1)//不能将参数的指针声明为const
{}
template
inline void ListRep::increment()
{
++m_useCount;
}
template
inline void ListRep::decrement()
{
if (--m_useCount == 0)
delete [] m_rep;
}
template
ListRep::~ListRep()//忘记加模板参数
{
delete [] m_rep;
}

template
class List
{
private:
int m_maxSize;
ListRep *m_ptr;
int m_size;
//检查一个索引是否为表中的正确的位置,如果表为空那么任何的位置都是错的
bool rightPo(int po) const;
//在表的某个位置插入数据val,在push中也使用这个函数
void intoList(int po, const T &val);
public:
//构造一个指定长度的线性表,如果没有给出长度那个有默认的值进行构造
explicit List(int maxSize = 5);
//将源表中的数据复制到目标表中
List(const List &l);
//模板类中可以不用指定参数把类名当作类型名
//但是作为返回值则要指定类的参数
const List& operator = (const List &l);
//两个表具有相同的长度,同时包含相同的数据
//并且数据在表中的位置具有一一对应咋这两个表相同
bool operator == (const List &l) const;
//利用==实现
bool operator != (const List &l) const;
//将表清空,删除表原来拥有的资源
void clear();
//表是否为空
bool empty() const;
//返回表的长度
intlistLengh() const;
//返回某个位置的数据,如果该位置正确用t返回这个数据并返回true,如果位置不正确
//则t的值是个为定义的数据,返回false
T getElem(int po) const;
//在某个位置之前插入一个 数据,如果该位置不是表中正确的位置
//则不向表中插入任何的数据
void insert(int po, const T &val);
//删除某个位置上的数据,如果该位置不是个正确的位置不做任何删除操作
void erase(int po);
//向表中压入数据
void push(const T& val);
};
template
bool List::rightPo(int po) const
{
if (m_size == 0)
return false;
else
{
if (po < 0 || po >= m_size)
return false;
else
return true;
}
}
template
void List::intoList(int po, const T &val)
{
if (m_size > m_maxSize)
m_maxSize *= 2;
ListRep *p = new ListRep(new T[m_maxSize]);
p->copy(m_ptr, m_size-1);
m_ptr->decrement();
m_ptr = p;

T *fp;
T *sp;
fp = (m_ptr->m_rep) + m_size -1;
sp = fp -1;
for (; fp != (m_ptr->m_rep)+po; --sp, --fp)
*fp = *sp;
*fp = val;
}

template
List::List(int maxSize):m_maxSize(maxSize),m_ptr(new ListRep(new T[m_maxSize]))
{
m_size = 0;
}
template
List::List(const List &l)
{
m_maxSize = l.m_maxSize;
m_size = l.m_size;
m_ptr = l.m_ptr;
m_ptr->increment();
}
template
const List& List::operator =(const List &l)
{
if (this != &l)
{
m_size = l.m_size;
m_maxSize = l.maxSize;
m_ptr->decrement();
m_ptr = l.m_ptr;
m_ptr->increment();
}
return *this;
}
template
bool List::operator == (const List &l) const
{
if (m_size == l.m_size)
{
if (m_ptr == l.m_ptr)
return true;
}
return false;
}
template
bool List::operator != (const List &l) const
{
return !(*this == l);
}
template
void List::clear()
{
m_size = 0;
m_maxSize = 5;
m_ptr->decrement();
m_ptr = new ListRep(new T[m_maxSize]); //使用模板类进行动态分配的时候
//要记得带上参数
}
template
inline bool List::empty() const
{
return m_size == 0;
}
template
inline int List::listLengh() const
{
return m_size;
}
template
T List::getElem(int po) const
{
if (rightPo(po))
return (m_ptr->m_rep)[po];
else
throw BadIndex();
}
template
void List::insert(int po, const T &val)
{
if (rightPo(po))
{
++m_size;
intoList(po, val);
}
else
throw BadIndex();
}
template
void List::erase(int po)
{
if (rightPo(po))
{
ListRep *p = new ListRep(new T[m_size]);
p->copy(m_ptr, m_size);
m_ptr->decrement();
m_ptr = p;
T *fp;
T *sp;
fp = (m_ptr->m_rep)+po;
sp = fp + 1;
--m_size;
for (; fp != (m_ptr->m_rep)+m_size; ++fp, ++sp)
*fp = *sp;
}
else
throw BadIndex();
}
template
void List::push(const T &val)
{
if (m_size + 1 <= m_maxSize)
{
(m_ptr->m_rep)[m_size] = val;
++m_size;
}
else
{
++m_size;
intoList(m_size, val);
}
}
#endif

    推荐阅读