您的位置:首页 > 其它

线性表(智能指针实现)

2007-12-06 14:56 337 查看
       
#ifndef LIST_H
#define LIST_H

#include <exception>
using namespace std;

//异常类,当查询的索引发生错误的时候抛出这个异常
class BadIndex :public exception
{
 public:
  virtual const char* what() const throw()
  {
   return "你输入的索引位置错误";
  }
};

template <typename T>
class List;

//计数类指针,用来在list中使用。没有定义复制控制,默认的就符合要求
template <typename P>
class ListRep
{
 private:
  P *m_rep;
  int m_useCount;
  friend class List<P>;
  ListRep(P* rep);
  ~ListRep();
  //将使用计数增加一
  void increment();
  //将使用计数减少一,当使用计数减小到0的时候删除指针所指向的资源
  //不能删除对象本身,那样会出错
  void decrement();
  //将一个指针所指向的资源复制到另一个指针中
  //这主要是在list中进行插入,删除以及向其中添加数据的时候使用
  //当进行这些操作的时候不能改变指针多指向的单元因为这个时候不止
  //一个指针指向它,所以要复制单独的一份进行操作
  void copy(const ListRep *lr, int size);
};

template <typename P>
void ListRep<P>::copy(const ListRep *lr, int size)  //不会对目标区间的大小做检查
{
 for (int i = 0; i != size; ++i)
  (this->m_rep)[i] = (lr->m_rep)[i];
}
template <typename P>
ListRep<P>::ListRep(P *rep):m_rep(rep), m_useCount(1)//不能将参数的指针声明为const
{}

template <typename P>
inline void ListRep<P>::increment()
{
 ++m_useCount;
}

template <typename P>
inline void ListRep<P>::decrement()
{
 if (--m
b379
_useCount == 0)
  delete [] m_rep;
}

template <typename P>
ListRep<P>::~ListRep()  //忘记加模板参数
{
 delete [] m_rep;
}

template <typename T>
class List
{
 private:
  int m_maxSize;
  ListRep<T> *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<T>& operator = (const List &l);

  //两个表具有相同的长度,同时包含相同的数据
  //并且数据在表中的位置具有一一对应咋这两个表相同
  bool operator == (const List &l) const;

  //利用==实现
  bool operator != (const List &l) const;

  //将表清空,删除表原来拥有的资源
  void clear();

  //表是否为空
  bool empty() const;

  //返回表的长度
  int  listLengh() 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 <typename T>
bool List<T>::rightPo(int po) const
{
 if (m_size == 0)
  return false;
 else
 {
  if (po < 0 || po >= m_size)
   return false;
  else
   return true;
 }
}

template <typename T>
void List<T>::intoList(int po, const T &val)
{
 if (m_size > m_maxSize)
  m_maxSize *= 2;
 ListRep<T> *p = new ListRep<T>(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 <typename T>
List<T>::List(int maxSize):m_maxSize(maxSize),m_ptr(new ListRep<T>(new T[m_maxSize]))
{
 m_size = 0;
}

template <typename T>
List<T>::List(const List &l)
{
 m_maxSize = l.m_maxSize;
 m_size = l.m_size;
 m_ptr = l.m_ptr;
 m_ptr->increment();
}

template <typename T>
const List<T>& List<T>::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 <typename T>
bool List<T>::operator == (const List &l) const
{
 if (m_size == l.m_size)
 {
  if (m_ptr == l.m_ptr)
   return true;
 }
 return false;
}

template <typename T>
bool List<T>::operator != (const List &l) const
{
 return !(*this == l);
}

template <typename T>
void List<T>::clear()
{
 m_size = 0;
 m_maxSize = 5;
 m_ptr->decrement();
 m_ptr = new ListRep<T>(new T[m_maxSize]);  //使用模板类进行动态分配的时候
              //要记得带上参数
}

template <typename T>
inline bool List<T>::empty() const
{
 return m_size == 0;
}

template <typename T>
inline int List<T>::listLengh() const
{
 return m_size;
}

template <typename T>
T List<T>::getElem(int po) const
{
 if (rightPo(po))
  return (m_ptr->m_rep)[po];
 else
  throw BadIndex();
}

template <typename T>
void List<T>::insert(int po, const T &val)
{
 if (rightPo(po))
 {
   ++m_size;
   intoList(po, val);
 }
 else
  throw BadIndex();
}

template <typename T>
void List<T>::erase(int po)
{
 if (rightPo(po))
 {
  ListRep<T> *p = new ListRep<T>(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 <typename T>
void List<T>::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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息