Chinaunix首页 | 论坛 | 博客
  • 博客访问: 264765
  • 博文数量: 45
  • 博客积分: 930
  • 博客等级: 准尉
  • 技术积分: 553
  • 用 户 组: 普通用户
  • 注册时间: 2012-01-22 17:53
文章分类

全部博文(45)

文章存档

2013年(5)

2012年(40)

分类: C/C++

2012-04-27 15:11:06

LinearList.h

点击(此处)折叠或打开

  1. #ifndef LINEARLIST_H
  2. #define LINEARLIST_H
  3. #include <iostream>
  4. using std::ostream;

  5. template <typename T>
  6. class Chain;

  7. template <typename T>
  8. ostream & operator<<(ostream & out, const Chain<T> & x);


  9. template <typename T>
  10. class ChainNode
  11. {
  12.     friend class Chain<T>;
  13. private:
  14.     T data;
  15.     ChainNode<T> *link;
  16. };
  17. template<typename T>
  18. class Chain {
  19.     friend ostream & operator << <T> (ostream & out , const Chain<T>& x);
  20. public:
  21.     Chain() {first = 0;}
  22.     ~Chain();
  23.     bool IsEmpty() const {return first == 0;}
  24.     int Length() const;
  25.     bool Find(int k, T& x) const;
  26.     int Search(const T& x) const;
  27.     Chain<T>& Delete(int k, T& x);
  28.     Chain<T>& Insert(int k, const T& x);
  29.     void Output(ostream & out) const;
  30. private :
  31.     ChainNode<T> *first;
  32. };

  33. template<typename T>
  34. Chain<T>::~Chain( )
  35. {
  36.     ChainNode<T> *next;
  37.     while (first) {
  38.         next = first->link;
  39.         delete first;
  40.         first = next;
  41.     }
  42. }

  43. template<typename T>
  44. int Chain<T>::Length() const
  45. {
  46.     ChainNode<T> *current = first;
  47.     int len = 0;
  48.     while (current) {
  49.         len++ ;
  50.         current = current->link;
  51.     }
  52.     return len;
  53. }

  54. template<typename T>
  55. bool Chain<T>::Find(int k, T& x) const
  56. {
  57.     if (k < 1) return false;
  58.     ChainNode<T> *current = first;
  59.     int index = 1;
  60.     while (index < k && current) {
  61.         current = current->link;
  62.         index++ ;
  63.     }
  64.     if (current)
  65.     {x = current->data; return true;}
  66.     return false;
  67. }

  68. template<typename T>
  69. int Chain<T>::Search(const T& x) const
  70. {
  71.     ChainNode<T> *current = first;
  72.     int index = 1;
  73.     while (current && current->data != x)
  74.     {
  75.         current = current->link;
  76.         index++;
  77.     }
  78.     if (current) return index;
  79.     return 0;
  80. }

  81. template<typename T>
  82. void Chain<T>::Output(ostream& out) const
  83. {
  84.     ChainNode<T> *current;
  85.     for (current = first; current; current = current->link)
  86.         out << current->data << " ";
  87. }

  88. template<typename T>
  89. Chain<T>& Chain<T>::Delete(int k, T& x)
  90. {
  91.     if (k < 1 || !first)
  92.         //throw OutOfBounds();
  93.         std::cout<<"OutOfBounds"<<std::endl;
  94.     ChainNode<T> *p = first;

  95.     if (k == 1)
  96.         first = first->link;
  97.     else {
  98.         ChainNode<T> *q = first;
  99.         for (int index = 1; index < k - 1 && q; index++)
  100.             q = q->link;
  101.         if (!q || !q->link)
  102.             //throw OutOfBounds();
  103.             std::cout<<"OutOfBounds"<<std::endl;
  104.         p = q->link;
  105.         q->link = p->link;
  106.     }
  107.     x = p->data;
  108.     delete p;
  109.     return *this;
  110. }

  111. template<typename T>
  112. Chain<T>& Chain<T>::Insert(int k, const T& x)
  113. {
  114.     if (k < 0)
  115.         //throw OutOfBounds();
  116.         std::cout<<"OutOfBounds"<<std::endl;
  117.     ChainNode<T> *p = first;

  118.     for (int index = 1; index < k && p; index++)
  119.         p = p->link;
  120.     if (k > 0 && !p)
  121.         //throw OutOfBounds();
  122.         std::cout<<"OutOfBounds"<<std::endl;
  123.     ChainNode<T> *y=new ChainNode<T>;
  124.     y->data = x;
  125.     if (k)
  126.     {
  127.         y->link = p->link;
  128.         p->link = y;
  129.     }
  130.     else
  131.     {
  132.         y->link = first;
  133.         first = y;
  134.     }
  135.     return *this;
  136. }

  137. template <typename T>
  138. ostream& operator<< (ostream& out, const Chain<T>& x)
  139. {
  140.     x.Output(out);
  141.     return out;
  142. }

  143. #endif

main.cpp

点击(此处)折叠或打开

  1. #include <iostream>
  2. #include "LinearList.h"

  3. using namespace std;

  4. int main()
  5. {
  6.     Chain<int> bob;
  7.     cout<<bob.IsEmpty()<<endl;
  8.     cout<<bob.Length()<<endl;
  9.     bob.Insert(0,33);
  10.     cout<<bob.Length()<<endl;
  11.     cout<<bob<<endl;
  12.     return 0;
  13. }

很奇怪的是这里没有LinearList.cpp文件,原因如下:
将类的定义和类成员函数的定义(实现文件)分别放入不同的文件,目标代码根据实现文件生成(和客户代码无关),并且和客户代码链接,这种做法对于类模板是不适用的。因为为函数传递参数在运行时起作用,而给类模板传递参数则在编译阶段起作用。由于类模板的实际参数在客户代码中指定,并且没有实际参数的编译器无法实例化一个函数模板,所以必须依赖客户代码才可编译模板的实现文件部分。

解决方案1:将类定义和函数模板定义直接包含在用户文件中,或者将类定义和函数模板定义都放在同一个头文件中;

解决方案2:将类定义的函数定义话在不同的文件中,但在头文件的末尾处包含实现文件。

不管用什么方法,客户代码要和函数定义一起编译。
阅读(1055) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~