• 基于模板类开发vector容器


    分析:容器类中要存放数组,而且数组类型不确定,所以应采用泛型编程,容器类要用到下标[]、赋值=、以及输出<<,所以应对这几个操作符进行重载。

    第一步:模板类的框架搭建

    #pragma once
    #include <iostream>
    using namespace std;
    
    
    template<typename T>
    class myvector
    {
    
        //重载左移运算符,输出类对象时等同于输出容器中的每个元素,注意模板类中的友元函数要加<T>
        friend ostream& operator<<<T>(ostream& out, myvector<T>& obj);
    public:
        //无参构造
        myvector();
    
        //有参构造
        myvector(int size);
    
        //拷贝构造
        myvector(const myvector& obj);
    
        //析构函数
        ~myvector();
    
        //重载[]
        T&  operator[](int index);
    
        //重载=
        myvector<T>& operator=(const myvector<T>& obj);
    
    private:
        
        //容器的空间
        T *p;
        //容器的容量
        int len;
    };

    第二步:模板类的模板函数编写

    #include "myvector.h"
    
    template<typename T>
    ostream& operator<<(ostream& out, myvector<T>& obj)
    {
        for (int i = 0; i <obj.len; i++)
        {
            out << obj.p[i] << " ";
        }
        out << endl;
        return out;
    }
    
        //无参构造
     template<typename T>
     myvector<T>::myvector()
     {
         this->len = 1;
         p = new T[len];
     }
    
        //有参构造
     template<typename T>
     myvector<T>::myvector(int size)
     {
         this->len = size;
         p = new T[len];
     }
    
        //拷贝构造   myvector<int>  t2(t1);
     template<typename T>
     myvector<T>::myvector(const myvector<T>& obj)
     {
         this->len = obj.size;
         p = new T[len];
     }
    
        //析构函数
       template<typename T>
        myvector<T>::~myvector()
        {
            if (p != NULL)
            {
                delete[] p;
                p = NULL;
                len = 0;
            }
        }
    
        //重载[]运算符   t1[5]
        template<typename T>
        T&  myvector<T>::operator[](int index)
        {
            return p[index];
        }
    
        //重载=运算符    t2=t1(把t1赋给t2),返回的是当前对象
        template<typename T>
        myvector<T>& myvector<T>::operator=(const myvector<T>& obj)
        {
           //第一步:清除内存
               if (p!=NULL)
               {
                   delete[] p;
                   p = NULL;
                   len = 0;
               }
           //第二步:将obj 的属性赋值给左值对象
               len = obj.len;
               p = new T[len];
            //第三步:添加元素 
               for (int i = 0; i < len; i++)
               {
                   p[i] = obj.p[i];
               }
               return *this;
        }

    第三步:老师类的编写

    #pragma once
    #include <iostream>
    using namespace std;
    class Teacher
    {
        friend ostream&  operator<<(ostream& out, Teacher& obj);
    public:
        //无参构造
        Teacher();
    
        //有参构造
        Teacher(char *name,int age);
    
        //重载拷贝构造(本类中含有指针属性,需要对拷贝构造进行重载以防止浅拷贝)
        Teacher(const Teacher& obj);
    
        //重载=运算符(本类中含有指针属性,需要对=运算符进行重载以防止浅拷贝)
        Teacher& operator=(const Teacher& obj);
    
        //析构
        ~Teacher();
    private:
    
        char*    p_name;
        int        age;
    };
    #include "Teacher.h"
    
    
    ostream&  operator<<(ostream& out, Teacher& obj)
    {
        out << obj.p_name << ", " << obj.age << endl;
        return out;
    }
    
        //无参构造
     Teacher::Teacher()
     {
         p_name = new char[1];
         strcpy_s(p_name,1, "");
         age = 20;
     }
    
        //有参构造
     Teacher::Teacher(char *name, int age)
     {
         p_name = new char[strlen(name) + 1];
         strcpy_s(p_name, strlen(name)+1,name);
         this->age = age;
     }
    
    //重载拷贝构造(本类中含有指针属性,需要对拷贝构造进行重载以防止浅拷贝)
     Teacher::Teacher(const Teacher& obj)
     {
         p_name = new char[strlen(obj.p_name) + 1];//开辟比obj的p_name长度大1 的char空间
         strcpy_s(p_name, strlen(obj.p_name) + 1,obj.p_name );//将名称拷贝,p_name与obj.p_name是两块独立的存储空间
         this->age = obj.age;
     }
        //重载=运算符(本类中含有指针属性,需要对=运算符进行重载以防止浅拷贝)
     Teacher& Teacher::operator=(const Teacher& obj)
     {
         //第一步:清除之前的内存
         if (p_name != NULL)
         {
             delete[] p_name;
             p_name = NULL;
             age = 20;
         }
         //第二步:拷贝数据
         p_name = obj.p_name;
         age = obj.age;
    
         //第三步:返回左值
         return *this;
     }
    
        //析构
     Teacher::~Teacher()
     {
         if (p_name != NULL)
         {
             delete[] p_name;
             p_name = NULL;
             age = 20;
         }
     }

    第四步:测试程序

    
    
    #include <iostream>
    #include "myvector.h"
    #include "myvector.cpp"
    #include "Teacher.h"
    using namespace std;
     

    int main()
    {
     //简单类型
     myvector<int>  t1(10);
     for (int i = 0; i < 10; i++)
     {
      t1[i] = i;
     }
     cout << t1 << endl;
     
     myvector<int>  t2(10);
     t2 = t1;//赋值操作
     cout << t2 << endl;

     //简单类型
     myvector<char>  t3(3);
     for (int j = 97; j < 100;j++)
     {
      t3[j-97] = j;
     }
     cout << t3 << endl;

     //复合类型
     Teacher obj1("张三",20), obj2("李四",30), obj3("王二",40), obj4("宋五",50);
     myvector<Teacher>  t4(4);
     t4[0] = obj1;//装值过程是一个拷贝过程,即t4[0]装的是obj1的副本,由于对Teacher类进行的重载,所以不会发生浅拷贝
     t4[1] = obj2;
     t4[2] = obj3;
     t4[3] = obj4;
     cout << t4 << endl;//输出t4实质上是输出Teacher类的每个对象,由于Teacher类对<<运算符进行了重载,所以顺利输出
     return 0;
    }

    第四步:测试结果

  • 相关阅读:
    admob 广告增加
    流量统计
    施乐 著名的帕洛阿尔托研究中心
    android Launcher
    系统集成
    jad 批量反编译class文件
    eclipse classes 文件不见
    悬浮窗不可触摸
    ios 相关
    android 屏幕切换
  • 原文地址:https://www.cnblogs.com/lyjbk/p/13065292.html
Copyright © 2020-2023  润新知