用类模板实现容器存储自定义数据类型(类似于STL里面的vector)

上一节里面已经提到了,用类模板存储自定义的数据类型,如Teacher类型时,需要重载Teacher类的拷贝构造函数,“=”操作符,"<<"操作符,特别要注意深拷贝和浅拷贝的问题。

例如:

  1 //1.myvector.h文件
  2 #ifndef MYVECTOR_H
  3 #define MYVECTOR_H
  4 
  5 #include <iostream>
  6 using namespace std;
  7 
  8 template<typename T>
  9 class Myvector
 10 {
 11     friend ostream& operator<<<T>(ostream& out,Myvector<T>& obj);
 12 public:
 13     Myvector(int size);//构造函数
 14     Myvector(Myvector<T>&);//拷贝构造函数
 15     ~Myvector();//析构函数
 16 
 17 public:
 18     Myvector<T>& operator=(const Myvector<T>& obj);
 19     T& operator[](int index);
 20     int getlen(){return my_len;}
 21 
 22 private:
 23     T*  my_space;//模板数组的首地址
 24     int my_len;//模板数组的长度,等于最大索引数+1
 25 };
 26 
 27 #endif
 28 
 29 
 30 //2.myvector.cpp文件
 31 #include <iostream>
 32 #include "myvector.h"
 33 
 34 
 35 using namespace std;
 36 
 37 //构造函数
 38 template<typename T>
 39 Myvector<T>::Myvector(int size)
 40 {
 41     my_len=size;
 42     my_space=new T[my_len];
 43     if(my_space==NULL)
 44     {
 45         cout<<"调用构造函数 分配内存失败!"<<endl;
 46         return;
 47     }
 48 }
 49 
 50 //拷贝构造函数,深拷贝。拷贝构造函数也是构造函数,一开始my_len,my_space的值都是没有的(随机数),不存在释放什么的,全是要靠自己复制才会有
 51 template <typename T>
 52 Myvector<T>::Myvector(Myvector<T>& obj)
 53 {
 54     my_len=obj.my_len;
 55     my_space=new T[my_len];
 56     
 57     for(int i=0;i<my_len;i++)
 58     {
 59         my_space[i]=obj.my_space[i];
 60     }
 61 }
 62 
 63 //析构函数
 64 template<typename T>
 65 Myvector<T>::~Myvector()
 66 {
 67     cout<<"调用模板类的析构函数"<<endl;
 68     if(my_space!=NULL)
 69     {
 70         delete [] my_space;
 71         my_space=NULL;
 72         my_len=0;
 73     }
 74 }
 75 
 76 //重载"[]"操作符
 77 template<typename T>
 78 T& Myvector<T>::operator[](int index)
 79 {
 80     return this->my_space[index];
 81 }
 82 
 83 
 84 //重载"="操作符
 85 template<typename T>
 86 Myvector<T>& Myvector<T>::operator=(const Myvector<T>& obj)
 87 {
 88     if(my_space!=NULL)
 89     {
 90         my_len=0;
 91         delete [] my_space;
 92         my_space = NULL;
 93     }
 94 
 95     my_len=obj.my_len;
 96     for(int i=0;i<my_len;i++)
 97     {
 98         my_space[i]=obj.my_space[i];
 99     }
100 
101     return *this;
102 }
103 
104 
105 //重载"<<"运算符
106 template<typename T>
107 ostream& operator<<(ostream& out,Myvector<T>& obj)
108 {
109     for(int i=0;i<obj.my_len;i++)
110     {
111         out<<obj.my_space[i]<<" ";
112     }
113     return out;
114 }
115 
116 
117 //3.main.cpp文件
118 #include <iostream>
119 #include"myvector.cpp"
120 #include"myteacher.h"
121 #include<string>
122 
123 using namespace std;
124 
125 class Teacher
126 {
127     friend ostream& operator<<(ostream& out,const Teacher& t);
128 public:
129     //构造函数,不带参
130     Teacher()
131     {
132         age=0;
133         name=NULL;
134     }
135 
136     //构造函数,带参
137     Teacher(int a,char* n)
138     {
139         age=a;
140         int name_len=strlen(n);
141         name=new char[name_len+1];
142         strcpy(name,n);
143     }
144 
145     //拷贝构造函数
146     Teacher(const Teacher& t)
147     {
148         age=t.age;
149         int name_len=strlen(t.name);
150         name=new char[name_len+1];
151         strcpy(name,t.name);
152     }
153 
154     //析构函数
155     ~Teacher()
156     {
157         cout<<"调用Teacher类的析构函数"<<endl;
158         if(name!=NULL)
159         {
160             age=0;
161             delete [] name;
162             name=NULL;
163         }
164     }
165 
166     //重载"="操作符
167     Teacher& operator=(Teacher& t)
168     {
169         if(name!=NULL)
170         {
171             delete [] name;
172             name=NULL;
173             age=0;
174         }
175     
176         int name_len=strlen(t.name);
177         name=new char[name_len+1];
178         strcpy(name,t.name);
179         age=t.age;
180 
181         return *this;
182     }
183 
184     void printT()
185     {
186         cout<<age<<" "<<name<<endl;
187     }
188 
189 
190 private:
191     int age;
192     char* name;
193 };
194 
195 ostream& operator<<(ostream& out,const Teacher& t)
196 {
197     out<<t.age<<" "<<t.name;
198     return out;
199 }
200 
201 
202 int main()
203 {
204     Teacher t1(26,"Wu"),t2(33,"Li");
205     
206     Myvector<Teacher> v(3);
207 
208     v[0]=t1;
209     v[1]=t2;
210 
211     cout<<v[0]<<endl;
212     cout<<v[1]<<endl;
213 
214 
215     
216     return 0;
217 }

上述代码的执行结果是:

26 Wu

33 Li

调用模板类的析构函数

调用Teacher类的析构函数

调用Teacher类的析构函数

调用Teacher类的析构函数

调用Teacher类的析构函数

调用Teacher类的析构函数

 

之所以会5次调用Teacher类的析构函数,是因为定义了1个myvector v(3),即v是包含3个元素的数组,定义了2个Teacher类的对象t1和t2。

然后把v[0]=t1,v[1]=t2,则v[2]是空的。执行析构函数的时候,要析构v里面的元素3次,即3次调用Teacher类的析构函数;调用Teacher类对象的析构函数2次,即t1和t2各析构一次,总共析构了2+3=5次。

 

posted @ 2018-03-08 12:00  8号prince  阅读(1444)  评论(0编辑  收藏  举报