这学期的大作业感觉挺简单的,就是写一个模板类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 }
在写这个代码时,由于英语差,把operator写成了operater,然后就是编译报错:expected initializer before ‘<<‘(‘+‘),什么鬼,明明是英语差,报这个错让我怎么找改,简直快要疯了。其实编译器对于operator这样的关键字颜色是不同的,然而我并没有发现,最后是对着别人的代码一步一步找到了,真是太不容易了,想到以后的debug之路就不寒而栗,还是加油吧。
大概就是这样。
原文:http://www.cnblogs.com/wenma/p/4548946.html