zoukankan      html  css  js  c++  java
  • 用类模板实现容器存储自定义数据类型(类似于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次。

  • 相关阅读:
    Django【十五】pillow模块使用
    Django【十四】内置的anth认证
    Django【十三】form组件。
    Django【十二】中间价
    Django【十一】cookie-sesson
    Django【十】Ajax
    Django【八】多表操作
    Django【九】事务和锁
    python协程
    python多线程
  • 原文地址:https://www.cnblogs.com/jswu-ustc/p/8527597.html
Copyright © 2011-2022 走看看