CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
IBM Rational 系统开发最佳实践工具包 WebSphere MQ 最佳实践 TOP 15
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  工具平台和程序库

写了个链表类,大家批批,看看有什么值得改进的地方。

楼主leechiyang(逮老鼠的狗算不算好猫?)2006-03-04 10:17:27 在 C/C++ / 工具平台和程序库 提问

#pragma   once  
   
  template<class   T>  
  class   CHebcaListIterator;  
   
  template<class   T>  
  class   CHebcaListItem  
  {  
  public:  
  CHebcaListItem()  
  {  
  Init();  
  };  
  CHebcaListItem(T   value)  
  {  
  Init();  
  data   =   value;  
  };  
  void   Init()  
  {  
  next   =   0;  
  previous   =   0;  
  }  
  T   data;  
  CHebcaListItem   *   previous;  
  CHebcaListItem   *   next;  
  };  
   
   
  template<class   T>  
  class   CHebcaList  
  {  
  public:  
  CHebcaList(void)  
  {  
  Init();  
  };  
   
   
  CHebcaList(CHebcaList<T>   &value)  
  {  
  Init();  
  RemoveAll();  
  CHebcaListIterator<T>   iter   =   value.GetIterator();  
  while(itor.Next())  
  {  
  PushBack(*itor.Current());  
  }  
  };  
   
  ~CHebcaList(void)  
  {  
  RemoveAll();  
  };  
   
  void   Init()  
  {  
  m_pHead   =   0;  
  m_pEnd   =   0;  
  m_nSize   =   0;  
  };  
   
  //取得迭代器,指向第一个元素前面.  
  CHebcaListIterator<T>   GetIterator()  
  {  
  return   CHebcaListIterator<T>(&m_pHead,   &m_pEnd);  
  };  
   
  //取得迭代器,指向最后一个元素后面.  
  CHebcaListIterator<T>   GetIteratorBack()  
  {  
  return   CHebcaListIterator<T>(&m_pHead,   &m_pEnd);  
  };  
   
  //在链表中position前面插入元素,position不能位于最后一个元素后面,  
  //如果需要在最后插入元素,用PushBack()  
  CHebcaListIterator<T>   Insert(CHebcaListIterator<T>   position,   T   value)  
  {  
  CHebcaListItem   *   pElement   =   new   CHebcaListItem<T>(value);  
  CHebcaListIterator<T>   iter   =   GetIterator();  
   
  if(position.m_pCurrent   ==   0)  
  {  
  if(m_pHead)  
  {  
  pElement->next   =   m_pHead;  
  m_pHead->previous   =   pElement;  
  m_pHead   =   pElement;  
  }  
  else  
  {  
  m_pHead   =   pElement;  
  m_pEnd   =   pElement;  
  }  
  }  
  else  
  {  
  if(position.m_pCurrent->previous)  
  {  
  pElement->next   =   position.m_pCurrent->previous->next;  
  pElement->previous   =   position.m_pCurrent->next->previous;  
  position.m_pCurrent->previous->next   =   pElement;  
  position.m_pCurrent->next->previous   =   pElement;  
  }  
  else  
  {  
  pElement->next   =   m_pHead;  
  m_pHead->previous   =   pElement;  
  m_pHead   =   pElement;  
  }  
  }  
   
  m_nSize   ++;    
  iter.SetCurrent(pElement);  
  return   iter;  
  };  
   
  //弹出最后一个元素  
  CHebcaListIterator<T>   PopBack()  
  {  
  CHebcaListIterator<T>   iter   =   GetIterator();  
  while(iter.HasNext())  
  {  
  iter.Next();  
  }  
  return   Remove(iter);  
  };  
   
  //弹出第一个元素  
  CHebcaListIterator<T>   PopFront()  
  {  
  CHebcaListIterator<T>   iter   =   GetIterator();  
  iter.Next();  
  return   Remove(iter);  
  };  
   
  //在最后插入一个元素  
  CHebcaListIterator<T>   PushBack(T   value)  
  {  
  CHebcaListIterator<T>   iter   =   GetIterator();  
  CHebcaListItem<T>   *   pElement   =   new   CHebcaListItem<T>(value);  
   
  if(m_pHead   ==   0)  
  {  
  m_pHead   =   pElement;  
  m_pEnd   =   pElement;  
  }  
  else  
  {  
  pElement->previous   =   m_pEnd;  
  m_pEnd->next   =   pElement;  
  m_pEnd   =   pElement;  
  }  
  m_nSize   ++;  
  iter.SetCurrent(m_pEnd);  
  return   iter;  
  };  
   
  //在前面插入一个元素  
  CHebcaListIterator<T>   PushFront(T   value)  
  {  
  CHebcaListIterator<T>   iter   =   GetIterator();  
  iter.Next();  
  return   Insert(iter,   value);  
  };  
   
  //删除position指向的一个元素  
  CHebcaListIterator<T>   Remove(CHebcaListIterator<T>   position)  
  {  
  if(position.m_pCurrent)  
  {  
  CHebcaListItem<T>   *   previous   =   position.m_pCurrent->previous;  
  CHebcaListItem<T>   *   next   =   position.m_pCurrent->next;  
  if(previous   &&   next)  
  {  
  previous->next   =   next;  
  next->previous   =   previous;  
  }  
  if(previous   &&   !next)  
  {  
  previous->next   =   0;  
  m_pEnd   =   previous;  
  }  
  if(!previous   &&   next)  
  {  
  m_pHead   =   next;  
  next->previous   =   0;  
  }  
  if(!previous   &&   !next)  
  {  
  m_pHead   =   0;  
  m_pEnd   =   0;  
  }  
  delete   position.m_pCurrent;  
  m_nSize   --;  
  }  
  return   GetIterator();  
  };  
   
  //删除所有的元素  
  void   RemoveAll()  
  {  
  CHebcaListIterator<T>   iter   =   GetIterator();  
  while(iter.HasNext())  
  {  
  PopFront();  
  iter   =   GetIterator();  
  }  
  };  
   
  //取得链表长度  
  int   GetSize()  
  {  
  return   m_nSize;  
  };  
   
  //链表是否为空  
  int   IsEmpty()  
  {  
  return   m_pHead   ==   0;  
  };  
   
  //赋值运算符重载  
  CHebcaList   &   operator   =(CHebcaList<T>   &value)  
  {  
  RemoveAll();  
  CHebcaListIterator<T>   iter   =   value.GetIterator();  
  while(itor.Next())  
  {  
  PushBack(*itor.Current());  
  }  
  return   *this;  
  };  
   
  //==运算符重载  
  int   operator==(CHebcaList<T>   &   value)  
  {  
  if(GetSize()   ==   value.GetSize())  
  {  
  CHebcaListIterator<T>   itor1   =   value.GetIterator();  
  CHebcaListIterator<T>   itor2   =   GetIterator();  
  while(itor1.Next())  
  {  
  if(*itor1.Current()   !=   *itor2.Next())  
  {  
  return   0;  
  }  
  }  
  return   1;  
  }  
  else  
  {  
  return   0;  
  }  
  };  
   
  protected:  
  CHebcaListItem<T>   *   m_pHead;  
  CHebcaListItem<T>   *   m_pEnd;  
  int   m_nSize;  
  };  
   
   
  //链表迭代器  
  //首元素前面等价于尾元素后面  
  //while(iter.Next()){...}遍历一遍后可以继续使用while(iter.Next()){...}进行遍历  
   
  template<class   T>  
  class   CHebcaListIterator  
  {  
  public:  
  CHebcaListIterator()  
  {  
  Init();  
  };  
   
  CHebcaListIterator(CHebcaListItem<T>   **   header,   CHebcaListItem<T>   **   ender)  
  {  
  Init();  
  m_ppHeader   =   header;  
  m_ppEnder   =   ender;  
  };  
   
  //后面是否还有元素  
  int   HasNext()  
  {  
  if(m_pCurrent)  
  {  
  return   m_pCurrent->next   !=   0;  
  }  
  else  
  {  
  return   *m_ppHeader   !=   0;  
  }  
  };  
   
  //向后移动一个元素,如果到了末尾元素后面返回0,否则返回指向当前元素的指针  
  T   *   Next()  
  {  
  if(m_pCurrent   ==   0)  
  {  
  m_pCurrent   =   *m_ppHeader;  
  }  
  else  
  {  
  m_pCurrent   =   m_pCurrent->next;  
  }  
   
  if(m_pCurrent)  
  {  
  return   &   m_pCurrent->data;  
  }  
  else  
  {  
  return   0;  
  }  
  };  
   
   
  //向前移动一个元素,如果到了首元素前面返回0,否则返回指向当前元素的指针  
  T   *   Previous()  
  {  
  if   (m_pCurrent   ==   0)  
  {  
  if(m_ppEnder)  
  {  
  m_pCurrent   =   *m_ppEnder;  
  if(m_pCurrent)  
  {  
  return   &   m_pCurrent->data;  
  }  
  else  
  {  
  return   0;  
  }  
  }  
  else  
  {  
  return   0;  
  }  
  }  
  else  
  {  
  m_pCurrent   =   m_pCurrent->previous;  
  if(m_pCurrent)  
  {  
  return   &   m_pCurrent->data;  
  }  
  else  
  {  
  return   0;  
  }  
  }  
  };  
   
  //返回指向当前元素的指针,如果当前位置为首元素前或尾元素后面,返回0  
  T   *   Current()  
  {  
  if(m_pCurrent)  
  {  
  return   &   m_pCurrent->data;  
  }  
  else  
  {  
  return   0;  
  }  
  };  
   
  //重置当前位置,指向首元素前或者末元素后面  
  void   Reset()  
  {  
  m_pCurrent   =   0;  
  };  
   
  //指定当前位置(一般不使用)  
  CHebcaListItem<T>   *   SetCurrent(CHebcaListItem<T>   *   current)  
  {  
  if(current)  
  {  
  m_pCurrent   =   *m_ppHeader;  
  while(m_pCurrent   !=   current)  
  {  
  m_pCurrent   =   m_pCurrent->next;  
  }  
  }  
  else  
  {  
  m_pCurrent   =   current;  
  }  
  return   m_pCurrent;  
  };  
  protected:  
  void   Init()  
  {  
  m_ppHeader   =   0;  
  m_ppEnder   =   0;  
  m_pCurrent   =   0;  
  };  
  CHebcaListItem<T>   **   m_ppHeader;  
  CHebcaListItem<T>   **   m_ppEnder;  
  public:  
  CHebcaListItem<T>   *   m_pCurrent;  
  };  
  问题点数:20、回复次数:10Top

1 楼kikikind(可乐)回复于 2006-03-04 15:41:15 得分 5

1.代码风格很好  
  2.继续多做练习  
  3.私人帮你顶一下!:)Top

2 楼zzw820626(偶要分,偶要星星)回复于 2006-03-06 17:11:18 得分 0

和sgi   的stl比比不就知道了Top

3 楼bluejugar(2046,那年我64.)回复于 2006-03-19 02:17:23 得分 5

小可不才,愿提一些建议:  
  1.加上预编译头#ifdef   ...   #define   ..   #endif  
  2.CHebcaListItem(T   value)  
  {  
  Init();  
  data   =   value;  
  };  
      一般来说,作为模板参数而言,因为不知道传入参数类型,用  
      CHebaclListItem(const   T&   value)可能要好一点.  
  3.类名不可理解,这会造成使用困难.简捷、规范的命名是所有C++库的安身立命之道。  
  4.三个类之间的关系太紧密。难以扩展和重用。适当的增加中间层,可能比较好一点。比如说对Iterator的重用等。  
  5。从楼主的代码可以看得出楼主是比较了解JAVA的,但JAVA里面的库有一个重要缺陷,就是各个库之间的接口不统一,相比之下,STL在这方面要稍加规范。  
   
  楼主的代码没有细看。总的来说还是写得不错的。继续加油干吧。Top

4 楼SeekTruth(鹤舞白沙)回复于 2006-03-20 16:50:37 得分 5

感觉iterator与container的耦合性太强Top

5 楼qkhhgutg(太子)回复于 2006-03-24 13:25:46 得分 0

接分Top

6 楼moonhappy(飞水)回复于 2006-03-25 08:00:32 得分 0

very   goodTop

7 楼leechiyang(逮老鼠的狗算不算好猫?)回复于 2006-03-25 11:22:03 得分 0

to:bluejugar  
  谢谢您的建议.  
  1.以后不用   #pragma   once   我也感觉#ifdef   ...   #define   ..   #endif更好些  
  2.CHebaclListItem(const   T&   value)确实好些,至少省掉了一次对象构造.  
  3.Hebca是公司缩写,不想和他人的代码产生冲突,所以就成这样了...  
        其他的常用避免命名冲突的方法都有什么?  
  4.确实是个问题.没有考虑过.  
  5.对java只是略微知道点,没写过一个程序:),   类里面的函数和使用方法大多是从stl里来的。但是对stl也不是很了解。  
   
  没看过什么设计模式的资料,只是凭空想象。所以请大家指正。Top

8 楼bitflying()回复于 2006-04-07 14:50:16 得分 5

1.   名字冲突可以用namespace解决。  
  2。各个类中的init()方法似无必要,可以用构造函数的初始化列表代替,比如:  
  CHebcaList(CHebcaList<T>   &value):m_pHead(0),m_pEnd(0),m_nSize(0)  
  3.   楼主能否解释一下,各个类中,数据成员都用protected修饰的意图是什么?这几个类似乎都是具体的实现类,不打算做基类。  
  4.   函数体定义全部都内联到类定义中,又不加inline关键字,这种风格的确是JAVA的。但如果用在C++中问题很多,最突出的问题是,如果头文件被included   到多个源文件中,在链接的时候会有名字冲突。  
   
  Top

9 楼leechiyang(逮老鼠的狗算不算好猫?)回复于 2006-04-27 08:50:51 得分 0

我也想把函数定义放到头文件中,实现部分放到CPP文件中,但是这种模板类编译通不过.如果可以这么做,还请给个例子.真的不知道怎么做,试了很长时间都不行.Top

10 楼sambian()回复于 2006-04-29 11:02:02 得分 0

这种方法不行.模板还没被实例化,不能放入CPP文件中.Top

相关问题

  • CSDN还有需要改进的地方???
  • csdn应该改进的地方
  • 二个水晶报表的BT问题,找遍了所有的地方从未涉及到类似的问题,求助!(很值得大家钻研)
  • 代替Ini的XmlConfig类,高手来看看有什么要改进的地方?
  • 大家帮忙看看http://www.dongke.com.cn/有哪些地方需要改进
  • 【一万】北京城里值得一去的几个地方
  • 改进一个表单提交前的的验证代码?
  • 下拉列表传值得问题
  • 麻烦各位看一下此存储过程,还有什么地方需要改进,实在太慢了。3KS
  • 新做的网站,大家PP,帮忙看看还有什么要改进的地方,帮顶有分……

关键词

  • c++
  • 函数
  • 指针
  • chebcalistiterator
  • pcurrent
  • chebcalistitem
  • getiterator
  • pelement
  • chebcalist
  • phead

得分解答快速导航

  • 帖主:leechiyang
  • kikikind
  • bluejugar
  • SeekTruth
  • bitflying

相关链接

  • C/C++ Blog
  • C/C++类图书
  • C/C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo