基于模板类开发vector容器

Posted lyjbk

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于模板类开发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;
}

第四步:测试结果

技术图片

以上是关于基于模板类开发vector容器的主要内容,如果未能解决你的问题,请参考以下文章

c++ 容器含义

序列式容器------vector类模板

Vector容器

用类模板实现容器(STL里面的vector)

11. 函数模板类模板实现vector顺序容器空间适配器

小白学习C++ 教程二十一C++ 中的STL容器Arrays和vector