iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++类模板实战之vector容器的实现
  • 792
分享到

C++类模板实战之vector容器的实现

2024-04-02 19:04:59 792人浏览 独家记忆
摘要

目录案例要求完成步骤1、封装数组类属性并完成有参构造以及析构函数2、提供对应的深拷贝构造函数防止调用析构时出错3、重载类内的赋值运算符防止浅拷贝问题出现4、提供尾部插入和删除的方法5

案例要求

可以对内置数据类型以及自定义数据类型的数据进行存储

将数组中的数据存储到堆区

构造函数中可以传入数组的容量

提供对应的拷贝构造函数以及operator=防止浅拷贝问题

提供尾插法和尾删法对数组中的数据进行增加和删除

可以通过下标的方式访问数组中的元素

可以获取数组中当前元素个数和数组的容量

完成步骤

1、封装数组类属性并完成有参构造以及析构函数

#pragma once
#include<iOStream>
using namespace std;
template<class T>
class Arrays
{
private:
    T* arr;//数组arr存放T类型的数据
    int capacity;//数组容量
    int size;//数组大小
public:
    Arrays(int capacity)
    {
        this->capacity = capacity;
        this->size = 0;
        this->arr = new T[this->capacity];
    }
    ~Arrays()
    {
        if (this->arr != NULL)
        {
            delete []this->arr;
            this->arr = NULL;
        }
    }
};

我把自己的这个数组类模板放到一个.hpp文件里,方便测试的时候调用。代码第一行是为了防止头文件重复包含,template里面的T就是数组的数据类型,根据调用时不同的指定存放不同类型的数据。将数组arr以及数组容量和大小进行封装,写在私有权限下即可 。然后提供该类的有参构造,参数列表传入的是数组容量,有参构造初始化了数组的容量以及大小并将数组开辟到了堆区。析构函数就是来清理堆区数据,如果我们开辟的堆区数组不为空,那就清理掉并将其指向NULL,这样可以防止野指针出现,避免异常。

2、提供对应的深拷贝构造函数防止调用析构时出错

    Arrays(const Arrays& p)
    {
        this->capacity = p.capacity;
        this->size = p.size;
        this->arr = new T[p.capacity];
        for (int i = 0; i < this->size; i++)
        {
            this->arr[i] = p.arr[i];
        }
    }

如果不提供深拷贝,那么编译器就会有:this->arr=p->arr 这行代码 ,那么一旦我们调用编译器提供的浅拷贝,当运行到析构函数时,就会出现重复删除地址的情况,必然会出现程序错误。所以我们要自己提供深拷贝构造函数,将上面的代码改为 this->arr= new T[p.capacity] ,这样调用析构的时候各自删除各的堆区数据,不会出现上述情况。最后利用for循环将传进来的对象的数据赋值给新开辟的数组。

3、重载类内的赋值运算符防止浅拷贝问题出现

    Arrays& operator=(const Arrays& p)
    {
        if (this->arr!=NULL)
        {
            delete []this->arr;
            this->arr = NULL;
            this->capacity = 0;
            this->size = 0;
        }
        //深拷贝过程
        this->capacity = p.capacity;
        this->size = p.size;
        this->arr = new T[this->capacity];
        for (int i = 0; i < p.size; i++)
        {
            this->arr[i] = p.arr[i];
        }
        return *this;
    }

当数组数据是对象的类型时,不能简单的将数组进行赋值操作,因为也牵扯到直接赋值出现一样的数组地址的情况,存在着深浅拷贝问题。赋值的时候是将传入参数的数据赋值给自己,因此先把自己的属性清空,然后就是深拷贝的实现了。最后返回的是*this,this指针能够指向不同成员属性,那么*this就是对象本身,然后看到返回值类型是对象引用,这样就可以实现对象间的连续赋值了。

4、提供尾部插入和删除的方法

    void insert_Arrays(const T&value)
    {
        if (this->capacity == this->size)
        {
            return;
        }
        this->arr[size] = value;
        this->size++;
    }
    void delete_Arrays()
    {
        if (this->size == 0)
        {
            return;
        }
        this->size--;
    }

尾插过程:先判断数组是否已经满了,如果不满就将形参赋值给当前数组最后一个下标的位置,然后更新数组下标,这样就能保证每次插入的数据都在数组末尾。 

尾删的实现:先判断数组是否为空,不为空的时候直接把数组大小减一即可,让编译器访问不到当前的最后一个数组元素。注意尾删的只是数据的指针,数组的地址并未删除。

5、重载[]得到数组中对应下标的数据信息

    T& operator[](int index)
    {
        return this->arr[index];
    }

如果数组内容是对象类型,是不存在对象数组的,所以要对[]运算符进行重载。返回值类型为数据类型的引用,也就是具体的数组内的值,传进去的整型参数就是数组下标。

6、提供get方法获取当前数组容量及大小

    int getSize()
    {
        return this->size;
    }
    int getCapacity()
    {
        return this->capacity;
    }

这里就是经典的get方法了,返回对应封装的成员属性 ,不做多解释。

7、提供打印函数测试基本数据类型和自定义数据类型的存储

#include"arrays.hpp"
class Hero
{
    friend void printHero(Arrays<Hero>&hero);
private:
    string name;
    string position;
public:
    Hero() {}
    Hero(string name, string position)
    {
        this->name = name;
        this->position = position;
    }
};
void printArrays(Arrays<int>arr)
{
    for (int i = 0; i < arr.getSize(); i++)
    {
        cout << arr[i] << " ";
    }
    cout << endl;
}
void printHero(Arrays<Hero>&hero)
{
    for (int i = 0; i < hero.getSize(); i++)
    {
        cout << "姓名:"<<hero[i].name<<" 位置:"<<hero[i].position<<endl;
    }
}
void test()
{
    cout << "普通类型数组测试:" << endl;
    cout << "输入数组容量为:" ;
    int n = 0; cin >> n;
    Arrays<int> array(n);
    cout << "输入数据:";
    for (int i = 0; i < array.getCapacity(); i++)
    {
        int value = 0;
        cin >> value;
        array.insert_Arrays(value);
    }
    cout << "打印数组信息:"<<endl;
    printArrays(array);
    array.delete_Arrays();
    cout << "删除一次尾部数据后打印数组信息:" << endl;
    printArrays(array);
}
void test1()
{
    cout << "自定义类型数组测试:" << endl;
    Hero h1("火舞","中单");
    Hero h2("韩信","打野");
    Hero h3("桑启","游走");
    Hero h4("守约","发育");
    Hero h5("关羽","对抗");
    Arrays<Hero> array(5);
    array.insert_Arrays(h1);
    array.insert_Arrays(h2);
    array.insert_Arrays(h3);
    array.insert_Arrays(h4);
    array.insert_Arrays(h5);
    printHero(array);
    array.delete_Arrays();
    cout << "删除一次尾部数据后打印数组信息:"<<endl;
    printHero(array);
}

首先引入之前封装的数组类头文件,提供printArrays和printHero函数来进行数组信息的打印,test和test1函数分别是整型数组和对象数组的测试。接下来看运行效果。

运行效果:

到此这篇关于c++类模板实战之vector容器的实现的文章就介绍到这了,更多相关C++ vector容器内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C++类模板实战之vector容器的实现

本文链接: https://www.lsjlt.com/news/153333.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C++类模板实战之vector容器的实现
    目录案例要求完成步骤1、封装数组类属性并完成有参构造以及析构函数2、提供对应的深拷贝构造函数防止调用析构时出错3、重载类内的赋值运算符防止浅拷贝问题出现4、提供尾部插入和删除的方法5...
    99+
    2022-11-13
  • C++模板以及实现vector实例详解
    目录函数模板类模板Vector实现简单的类模板实现代码及测试:win msvc编译器的实现:容器的空间配置器运算符重载与迭代器实现最终vector的实现代码总结函数模板 函数模板:是...
    99+
    2022-11-12
  • C++ vector类的模拟实现方法
    vector和string虽然底层都是通过顺序表来实现的,但是他们利用顺序表的方式不同,string是指定好了类型,通过使用顺序表来存储并对数据进行操作,而vector是利用了C++...
    99+
    2022-11-12
  • C++ STL vector的模拟实现
    1. vector的介绍和使用 vector是表示可变大小数组的序列容器。 就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对v...
    99+
    2022-11-12
  • C++模板基础之函数模板与类模板实例详解
    目录泛型编程 函数模板 函数模板的概念 函数模板的格式 函数模板的原理 函数模板的实例化 函数模板的匹配原则 类模板 类模板的定义格式 类模板的实例化 总结泛型编程  ...
    99+
    2022-11-12
  • C++模拟实现vector的方法
    今天小编给大家分享一下C++模拟实现vector的方法的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。1. 模拟实现vecto...
    99+
    2023-07-02
  • C++类和对象实战之Date类的实现方法
    目录零、前言一、Date类相关接口二、具体接口函数实现1、获取月份天数2、Date打印3、Date构造函数4、Date析构函数5、Date拷贝构造函数6、Date赋值重载函数7、Da...
    99+
    2022-11-12
  • c++ vector模拟实现的全过程
    一、vector是什么? vector是表示可变大小数组的序列容器,它也采用连续存储空间来存储元素,因此可以采用下标对vector的元素进行访问,它的大小是动态改变的,vector...
    99+
    2022-11-12
  • C++中vector的模拟实现实例详解
    目录vector接口总览 默认成员函数 构造函数 拷贝构造 赋值重载 析构函数 迭代器相关函数 begin和end 容量相关函数 size和capacity reserve resi...
    99+
    2022-11-12
  • C++之list容器模拟实现方式
    目录总述一、节点类二、迭代器类成员变量构造函数*重载->重载“++”“==“和”!=”三、反向迭代器类成...
    99+
    2023-02-05
    C++ list容器 list容器模拟实现 模拟实现list
  • C++之list容器模拟怎么实现
    这篇“C++之list容器模拟怎么实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C++之list容器模拟怎么实现”文章吧...
    99+
    2023-07-05
  • c++中vector的使用和模拟实现
    一、接口介绍 1、插入数据 void push_back(const T& x) 在当前vector尾部插入x,如果容量不够扩大二倍。 iterator insert(it...
    99+
    2022-11-12
  • C++模拟实现vector的示例代码
    目录1.前言2.vector介绍3.vector模拟实现3.1 迭代器接口3.2 vector元素操作3. 3 构造与析构1.前言 大家在学习C++的时候一定会学到STL(标准模板库...
    99+
    2022-11-13
  • C++中STL vector的模拟实现示例
    这篇文章主要介绍C++中STL vector的模拟实现示例,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1. vector的介绍和使用vector是表示可变大小数组的序列容器。就像数组一样,vector也采用的连续存...
    99+
    2023-06-14
  • C++入门之vector的底层实现详解
    目录前言定义初始结构声明构造函数容量有关操作获取有效数据大小size()获取数据容量capacity()增加容量reserve()重置大小resize()迭代器数据操作尾插push_...
    99+
    2022-11-12
  • c++中vector模拟实现的示例分析
    这篇文章将为大家详细讲解有关c++中vector模拟实现的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、vector是什么?vector是表示可变大小数组的序列容器,它也采用连续存储空间来存储...
    99+
    2023-06-14
  • C++如何实现顺序栈(使用模板类)
    目录一、思路二、遇到问题三、实现程序一、思路 1.用数组存储栈中的元素;2.用top保存栈顶的位置;3.进栈:top加1,然后在数组中的top位置插入x;4.出栈:top减1 二、遇...
    99+
    2022-11-13
  • 详解C++中vector的理解以及模拟实现
    目录vector介绍vector常见函数介绍vector模拟实现及迭代器失效讲解vector介绍 vector文档 1.vector是表示可变大小数组的序列容器。 2.就像数组一样,...
    99+
    2023-03-08
    C++ vector实现 C++ vector
  • C++OpenCV实战之网孔检测的实现
    目录前言一、HSV通道转换二、图像修复2.1 OpenCV函数实现2.2 MyFunction三、轮廓提取四、效果显示五、源码总结前言 前段时间,有位粉丝私信我,给我发了一张图片,如...
    99+
    2022-11-13
  • C++OpenCV实战之标记点检测的实现
    在实际应用中,能够直接利用霍夫圆检测这些理想方法的应用场景是非常少的,更多的是利用拟合的办法去寻找圆形。 大致思路如下,首先先选择要处理的ROI部分,记录下该图的左上点在原图的坐标,...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作