一个数组类【模板类】

这学期的大作业感觉挺简单的,就是写一个模板类MyList,实现一些Python中的list的操作(类似于c++中的vector,但是不支持迭代器)。这些功能都很简单,唯一麻烦的就是模板类特别烦,特别是友元函数,首先要声明这个类,然后声明是函数的声明,然后是类中友元函数的声明,最后是实现。友元函数的声明还有一个问题就是声明时在函数名后面要加上一个<>就像这样:

friend void Qsort<>(T a[],int low,int high,bool less);

还有一个要注意的就是所有在类外定义的成员函数必须写成模板函数。

类的头文件如下:

技术分享
 1 //MyList.h
 2 #ifndef MyList_h
 3 #define MyList_h
 4 
 5 #include <iostream>
 6 using namespace std;
 7 
 8 class rangeerror{}; //the error class used to catch error
 9 template <class T> class MyList;
10 // the following are friend functoins statements
11 template <class T> void Qsort(T a[],int, int, bool);
12 template <class T> ostream & operator<<(ostream &os,const MyList<T> &obj);
13 template <class T> MyList<T> operator+ (const MyList<T> &l1, const MyList<T> &l2);
14 template <class T> MyList<T> operator+ (const MyList<T> &l1, const T &item);
15 template<class T>
16 class MyList{
17     friend void Qsort<>(T a[],int low,int high,bool less);
18     friend ostream &operator<< <>(ostream &os, const MyList<T> &obj);
19     friend MyList<T> operator+ <>(const MyList<T> &l1, const MyList<T> &l2);
20     friend MyList<T> operator+ <>(const MyList<T> &l1, const T &item);  
21 private:
22     T *a;
23     int size;
24     int capa;   //record the space available
25     void double_space(); // double the remained space if not enough
26 public:    
27     
28     MyList(int s = 0):size(s),capa(s){ //constructor
29         if (capa == 0) capa = 100;
30         a = new T[capa];
31     }
32     MyList(int num, const T &item){  //constructe a object with num items
33         size = capa = num;
34         a = new T[capa];
35         for (int i = 0;i < num;++i) a[i] = item;
36     }
37     MyList(const MyList &l){   // copy constructor
38         size = capa = l.size;
39         a = new T[capa];
40         for (int i = 0;i < size;++i) a[i] = l.a[i];
41     }
42     MyList(T* arr, int len){//constructe by the previous len items of arr
43         size = capa = len;
44         a = new T[capa];
45         for (int i = 0;i < len;++i) a[i] = arr[i];
46     }
47     void push(const T &item);//add item to the last of MyList
48     T pop();                //delete the last item and return it
49     void insert(int index, const T &item);//insert item in the position of index
50     void clean(){erase(0,size-1);}//clear the list
51     int get_size() {return size;}//return the number of MyList
52     void erase(int start, int end); //delete items between start(included) and end(included)
53     T get_item(int index);//return index-th item
54     MyList get_item(int start, int end);//return a sublist from start to end(negative indexes are allowed
55     int count(const T &item);//return the number of items in MyList which equal to item
56     void remove(const T &item);//delete the first element in MyList which equals to item
57     T &operator[](int index); // index operator which return the reference of the element
58     MyList &operator = (const MyList &l);// assignment
59     MyList &operator += (const T &item);//equal to push(T item)
60     MyList &operator += (const MyList &l);//add a new MyList in the end of list
61     void sort(bool less=true);//quick sort the list(if less is true, the order is by increasing, other wise decreasing
62     void reverse();//reverse the elements in MyList
63     ~MyList(){delete [] a;} //destrctor
64 };
65 
66 #endif
头文件

实现文件及测试代码:

技术分享
  1 // Mylist.cpp : the realization of class MyList
  2 
  3 #include "stdafx.h"
  4 #include "Mylist.h"
  5 
  6 template <class T>
  7 MyList<T> operator+(const MyList<T> &l1,const MyList<T> &l2){
  8     int len = l1.size + l2.size;
  9     MyList<T> l3(len);
 10     for (int i = 0;i < l1.size;++i) l3.a[i] = l1.a[i];
 11     for (int i = l1.size;i < len;++i) l3.a[i] = l2.a[i-l1.size];
 12     return l3;
 13 }
 14 template <class T>
 15 ostream & operator<< (ostream &os,const MyList<T> &l){
 16     for (int i = 0;i < l.size;++i) os<<l.a[i]<< ;
 17     os<<endl;
 18     return os;
 19 }
 20 template <class T> 
 21 MyList<T> operator+(const MyList<T> &l,const T &item){
 22     MyList<T> l2(l.size+1);
 23     for (int i = 0;i < l.size;++i) l2.a[i] = l.a[i];
 24        l2.a[l2.size-1] = item;
 25        return l2;
 26 }
 27 template <class T>
 28 void MyList<T>::double_space(){//数组大小不够的时候将数组大小翻倍的操作。
 29     capa *= 2;
 30     T *newa = new T[capa];
 31     for (int i = 0;i < size;++i) newa[i] = a[i];
 32     delete [] a;
 33     a = newa;
 34 }
 35 
 36 template <class T>
 37 void MyList<T>::push(const T &item){
 38     if (size == capa) double_space();
 39     a[size++] = item;
 40 }
 41 template <class T>
 42 T MyList<T>::pop(){
 43     try {
 44         if (size==0) throw rangeerror();
 45         T tem = a[size-1];
 46         size--;
 47         return tem;
 48     }
 49     catch(rangeerror) {
 50         cout<<"out of range!";
 51         exit(0);
 52     }
 53 }
 54 template <class T>
 55 void MyList<T>::insert(int index,const T &item){
 56     try {
 57         if (index<0 || index>=size) throw rangeerror();
 58         if (size == capa) double_space();
 59         for (int i = size;i > index;--i) a[i] = a[i-1];
 60         a[index] = item;
 61         size++;
 62     }
 63     catch(rangeerror){
 64         cout<<"out of range!";
 65         exit(0);
 66     }
 67 }
 68 template <class T>
 69 void MyList<T>::erase(int start,int end){
 70     try {
 71         if (start<0 || end>size-1 || end<start) throw rangeerror();
 72         for (int i = end+1;i < size;++i) a[start+i-end-1] = a[i];
 73         size -= end-start+1;
 74     }
 75     catch (rangeerror){
 76         cout<<"out of range!";
 77         exit(0);
 78     }
 79 }
 80 template <class T>
 81 T MyList<T>::get_item(int index){
 82     try{
 83         if (index<0 || index>size-1) throw rangeerror();
 84         return a[index];
 85     }
 86     catch(rangeerror) {
 87         cout<<"out of range!";
 88         exit(0);
 89     }
 90 }
 91 template <class T>
 92 MyList<T> MyList<T>::get_item(int start,int end){
 93     try{
 94         if (start<0) start += size;
 95         if (end<0) end += size;
 96         if (start>=size || start<0 ||end>=size||end<0) throw rangeerror();
 97         int len = end - start + 1;
 98         if (len>0){
 99             MyList<T> t(len);
100             for (int i = 0;i < len;++i) t.a[i] = a[start+i];
101             return t;
102         }else{
103             MyList<T> t;
104             return t;
105         }        
106     }
107     catch(rangeerror){
108         cout<<"out of range!";
109         exit(0);
110     }
111 }
112 template <class T>
113 int MyList<T>::count(const T &item){
114     int num = 0;
115     for (int i =0;i < size;++i) if (a[i] == item) num++;
116     return num;
117 }
118 template <class T>
119 void MyList<T>::remove(const T &item){
120     for (int i = 0;i < size;++i) if (a[i] == item){
121         erase(i,i);
122         break;
123     }
124 }
125 template <class T>
126 void MyList<T>::reverse(){
127     if (size<2) return;
128     for (int i = 0;i < size/2;++i) {
129         T tem = a[i];
130         a[i] = a[size - i - 1];
131         a[size-i-1] = tem;
132     }
133 }
134 template <class T>
135 void MyList<T>::sort(bool less){
136     if (size==0) return;
137     Qsort(a,0,size-1,less); 
138 }
139 template <class T>
140 MyList<T>& MyList<T>::operator = (const MyList<T> &l){
141     if (this == &l) return *this;
142     delete [] a;
143     capa = size = l.size;
144     a = new T[size];
145     for (int i = 0;i < size;++i) a[i] = l.a[i];
146     return *this;
147 }
148 template <class T>
149 MyList<T>& MyList<T>::operator +=(const T &item){
150     push(item);
151     return *this;
152 }
153 template <class T>
154 MyList<T>& MyList<T>::operator +=(const MyList<T> &l){
155     *this = *this + l;
156     return *this;
157 }
158 template <class T>
159 T &MyList<T>::operator[](int index){
160        try {
161            if (index < 0 || index >= size) throw rangeerror();
162         return a[index];
163     }
164        catch(rangeerror){
165         cout<<"out of range!";
166         exit(0);
167     }
168 } 
169 template <class T>
170 void Qsort(T a[],int low,int high,bool less){
171     if (high<=low) return;
172     T tem = a[low];
173     int l = low,r = high;
174     if (less) {
175         do {
176             while (l<r && a[r]>=tem) r--;
177             if (l<r) a[l++] = a[r];
178             while (l<r && a[l]<=tem) l++;
179             if (l<r) a[r--] = a[l];
180             a[l] = tem;
181         }while(l!=r);
182         
183     }else{
184         do {
185             while (l<r && a[r]<=tem) r--;
186             if (l<r) a[l++] = a[r];
187             while (l<r && a[l]>=tem) l++;
188             if (l<r) a[r--] = a[l];
189             a[l] = tem;
190         }while (l!=r);        
191     }
192     Qsort(a,low,l-1,less);
193     Qsort(a,l+1,high,less);
194 }
195 
196 // the following is the test code
197 int _tmain(int argc, _TCHAR* argv[])
198 {
199     MyList<int> a, b;
200     int i;
201     for (i=0; i<5; ++i)
202         a.push(i);// a = [0, 1, 2, 3, 4]
203     a[3] = 15; // a = [0, 1, 2, 15, 4]
204     a.sort();// a = [0, 1, 2, 4, 15]
205     a.reverse();// a = [15, 4, 2, 1, 0]
206     a += 12;// a = [15, 4, 2, 1, 0, 12]
207     for (i=0; i<a.get_size(); ++i)
208         cout<<a[i]<<endl;
209     b = a.get_item(4, -3); // b = [] *若start > end,返回空数组
210     b = a.get_item(3, -1);cout<<b<<endl;// b = [1, 0, 12] 
211     a += b;// a = [15, 4, 2, 1, 0, 12, 1, 0, 12]
212     for (i=0; i<a.get_size(); ++i)
213         cout<<a.get_item(i)<<endl;
214     cout<<a.count(5)<<endl;
215     b.clean();// b = []
216     cout<<b.get_size()<<endl;
217     a.erase(2, 5);// a = [15, 4, 0, 12]
218     b = a + a;// b = [15, 4, 0, 12, 15, 4, 0, 12]
219     b.insert(3, 116);// b = [15, 4, 0, 116, 12, 15, 4, 0, 12]
220     b.remove(4);// b = [15, 0, 116, ...]
221     cout<<b<<endl;
222     MyList<double> c(10, 3.14);
223     for (i=0; i<100; ++i) c.push(1.1*i);
224     cout<<c.get_item(100, 105)<<endl;
225     return 0;
226 }
cpp文件

在写这个代码时,由于英语差,把operator写成了operater,然后就是编译报错:expected initializer before ‘<<‘(‘+‘),什么鬼,明明是英语差,报这个错让我怎么找改,简直快要疯了。其实编译器对于operator这样的关键字颜色是不同的,然而我并没有发现,最后是对着别人的代码一步一步找到了,真是太不容易了,想到以后的debug之路就不寒而栗,还是加油吧。

大概就是这样。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。