C++day7

2023-09-14 21:23:45

 仿照vector手动实现自己的myVector,最主要实现二倍扩容功能

代码

头文件

#ifndef TEST_H
#define TEST_H
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
template <typename T>
class Myvector
{
public:
    Myvector();                     //无参构造
    Myvector(int n,const T num);    //有参构造
    Myvector(const Myvector &other);//拷贝构造
    ~Myvector();                    //析构函数
    int capacity();                 //返回当前所能容纳的元素个数
    void push_back(const T &num);   //在末尾插入元素
    int size_data();                //返回当前存储的元素个数
    void assign(int n,const T num); //向容器中赋值
    T& at(int pos);                 //返回指定位置的数据
    void clear();                   //清空
    bool empty();                   //判空
    T& front();                     //返回第一个数据
    T& back();                      //返回最后一个数据
    T* begin();                     //返回第一个数据的地址
    T* end();                       //返回最后一个数据的地址
    T* insert(T* p,const T& num);   //指定位置插入数据
    void pop_back();                //删除最后一个数据
    void show();                    //遍历
private:
    T* data;      //存数据
    int size;     //存储数据个数最大值
    int number;   //存储当前数据个数
};
#endif // TEST_H

源代码

#include "test.h"
template <typename T>
Myvector<T>::Myvector():data(new T),size(1),number(0){}     //无参构造
template <typename T>
Myvector<T>::Myvector(int n,const T num)    //有参构造
{
    //输入了n个数据
    size = n;
    number = n;
    data = new T[n];
    for (int i = 0; i < n; ++i) //将申请到的空间都赋值为num
    {
        data[i] = num;
    }
}
template <typename T>
Myvector<T>::Myvector(const Myvector &other)//拷贝构造
{
    size = other.size;
    data = new T[other.size];
    for (int i = 0; i < other.size; ++i)
    {
        data[i] = other.data[i];
    }
}
template <typename T>
Myvector<T>::~Myvector()                    //析构函数
{
    delete []data;
}
template <typename T>
int Myvector<T>::capacity()     //返回当前所能容纳的元素个数
{
     return size;
}
template <typename T>
void Myvector<T>::push_back(const T &num)      //在末尾插入元素
{
    if(number == size) //判断当前是否已满
    {
        int i = 0;
        T* data_new = new T[size*2];  //二倍扩容
        size = size * 2;
        while(i < number)       //将旧区的数据内容赋给新区
        {
            data_new[i] = data[i];
            i++;
        }
        delete []data;          //释放旧区
        data = data_new;        //指向新区
        data_new = nullptr;     //新指针置空
        data[number] = num;     //插入元素
        number++;               //存储数量加1
    }
    else if(number < size)
    {
        data[number] = num;
        number++;
    }
}
template <typename T>
int Myvector<T>::size_data()       //返回当前存储的元素个数
{
    return number;
}
template <typename T>
void Myvector<T>::assign(int n,const T num) //向容器中赋值
{
    if(n > size) //判断要重写的数据个数是否最大存储个数
    {
        int i = 0;
        while(n > size)
        {   //之前的空间不够,释放并重新给空间
            delete []data;
            data = nullptr;
            data = new T[size*2];  //二倍扩容
            size = size * 2;
        }
        while(i < n)       //循环赋值
        {
            data[i] = num;
            i++;
        }
        number = n;             //存储数量改变
    }
    else if(n < size)
    {
        int i = 0;
        while(i < n)       //循环赋值
        {
            data[i] = num;
            i++;
        }
        if(n > number)  //如果重写个数大于已有个数
        {
            number = n; //更新已有个数
        }
    }
}
template <typename T>
T& Myvector<T>::at(int pos) //返回指定位置的数据
{
    if(pos > number || pos < 0)
    {
        throw T(1);  //抛出异常
    }
    else
    {
        return data[pos-1];  //返回指定位置数据
    }
}
template <typename T>
void Myvector<T>::clear() //清空
{
    memset(data,0,sizeof(data[0])*size);
    number = 0;
}
template <typename T>
bool Myvector<T>::empty()    //判空
{
    return number == 0;
}
template <typename T>
T& Myvector<T>::front() //返回第一个数据
{
    return data[0];
}
template <typename T>
T& Myvector<T>::back() //返回最后一个数据
{
    return data[number-1];
}
template <typename T>
T* Myvector<T>::begin() //返回第一个数据的地址
{
    return &data[0];
}
template <typename T>
T* Myvector<T>::end() //返回最后一个数据的地址
{
    return &data[number];
}
template <typename T>
T* Myvector<T>::insert(T* p,const T& num)   //指定位置插入数据
{
    int j = 0;
    while(&data[0]+j != p) //寻找输入的是第几个数据的地址
    {
        j++;
    }
    if(number == size || j+1 > size) //判断当前是否已满
    {
        int i = 0;
        T* data_new = new T[size*2];  //二倍扩容
        size = size * 2;
        while(i < number)       //将旧区的数据内容赋给新区
        {
            data_new[i] = data[i];
            i++;
        }
        delete []data;          //释放旧区
        data = data_new;        //指向新区
        data_new = nullptr;     //新指针置空
        //将指定位置之后的数据全都后移一位
        for(int k = number,i = j;i < number;i++,k--)
        {
                data[k] = data[k-1];
        }
        data[j] = num;     //插入元素
        number++;               //存储数量加1
        return &data[j];
    }
    else if(number < size && j < size)
    {
        //将指定位置之后的数据全都后移一位
        for(int k = number,i = j;i < number;i++,k--)
        {
                data[k] = data[k-1];
        }
        data[j] = num;     //插入元素
        number++;               //存储数量加1
        return &data[j];
    }
}
template <typename T>
void Myvector<T>::pop_back() //删除最后一个数据
{
    number--;
}
template <typename T>
void Myvector<T>::show() //遍历
{
    int i = 0;
    for(;i < number;i++)
    {
        cout << data[i] << "\t";
    }
    cout << endl;
}

测试函数

#include "test.h"
#include "test.cpp"
int main()
{
    Myvector<int> v1(6,3);
    v1.show();
    cout << "1当前能够容纳的元素个数:" << v1.capacity() << endl;
    v1.push_back(5);       //在末尾插入一个数
    v1.show();
    cout << "最后一个元素:" << v1.at(7) << endl;
    cout << "2当前能够容纳的元素个数:" << v1.capacity() << endl;
    cout << "第一个数:" << v1.front() << endl;
    cout << "最后一个数:" << v1.back() << endl;
    v1.insert(v1.begin()+3,5);      //指定位置插入
    v1.show();
    cout << "3当前能够容纳的元素个数:" << v1.capacity() << endl;
    v1.pop_back();      //删除末尾元素
    v1.show();
    cout << "4当前能够容纳的元素个数:" << v1.capacity() << endl;
    v1.assign(13,1);  //向容器中赋值
    v1.show();
    cout << "5当前能够容纳的元素个数:" << v1.capacity() << endl;
    return 0;
}

运行结果 

思维导图 

更多推荐

UML基础与应用之对象图

什么是对象图?对象图表示一组对象及它们之间的关系,是某一时刻系统详细信息的快照,描述系统交互的静态图形,它由协作的对象组成,但不包含在对象之间传递的任何消息。因为对象是类的实例化,所以说某一时刻系统中的某一类中的某一个对象和另一类中某一个对象之间的关系就可以说是对象图,表示类图的一个实例。对象图:表示在某一时刻一组对象

vue消息订阅与发布

1.知识点是一种组件间通信的方式,适用于任意组件间通信2.使用步骤“消息订阅与发布”可依赖的第三方很多,这里使用pubsub-js库1.安装pubsub:npmipubsub-js2.引入:importpubsubfrom'pubsub-js'3.接收数据:A组件想接收数据,则在A组件中订阅消息,订阅的回调留在A组件中

Java多线程(一)

文章目录一、程序、进程、线程基本概念1.程序(program)2.进程(process)3.线程(thread)二、单核CPU和多核CPU的理解三、并行和并发1.并行2.并发四、创建多线程的方式一(继承Thread类)1.创建两个分线程,其中一个线程遍历100以内的偶数,另外一个线程遍历100以内的奇数2.售票案例五、

wait函数与waitpid函数

1.函数介绍2.wait函数#include<sys/types.h>#include<sys/wait.h>pid_twait(int*wstatus);功能:等待任意一个子进程结束,如果该子进程结束了,此函数会回收子进程的资源参数:-int*wstatus:进程退出时的状态信息,传入的是一个int类型的地址,传出参

MySQL学习笔记

目录注释1、启动和关闭MYSQL服务2、库的增删改查3、表的增删改查3.1创建表3.2修改表3.3删除4、数据类型4.1字符串:char(num)与varchar(num)的区别4.2整型4.3浮点型4.4日期型4.5枚举型注释单行注释:#注释文字(没空格)单行注释:--注释文字(有空格)多行注释:/*注释文字*/,注

高效畅通的iOS平台S5配置指南

在iOS平台上,使用S5代理ip访问互联网是一种非常有用的技巧。无论是为了保证隐私安全,还是解决网络限制问题,S5代理ip都能为您提供更快、更稳定的互联网访问体验。本文将为您详细介绍如何在iOS平台上配置和使用S5代理ip,让您的网络畅通无阻!一、了解S5代理ip的工作原理S5代理ip是一种网络代理协议,可以让您的设备

仿网易云-360度混响

一直在用网易云音乐听歌,感觉他的这个动效还是挺不错的,最近也是想试试canvas绘图相关的。尝试了几次之后感觉效果还不错,不过距离网易云的还是有些差距。本期准备仿照制作如下效果:偷偷使用最近比较流行的罗刹海市的音乐来展示这个效果。效果展示如下:效果展示网站参考文档具体的流程大体上就是获取音频数据,然后根据音频数据绘制在

zookeeper集群

一,zookeeper定义Zookeeper是一个开源的分布式的,为分布式框架提供协调服务的Apache项目。二,zookeeper工作机制Zookeeper从设计模式角度来理解:是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理大家都关心的数据,然后接受观察者的注册,一旦这些数据的状态发生变化,Zooke

【Linux】nohub指令--终端退出后命令仍旧执行

文章目录0、背景1、作用2、语法3、用法演示4、关于2>&10、背景Shell中,执行一个持续进行的指令,会"霸屏",即你想再执行其他指令,要么重开个shell终端,要么退出这个执行。1、作用nohub,即nohangup(不挂起),用于在系统后台不挂断地运行命令,Ctrl+C退出终端后命令依旧执行。2、语法nohup

JavaScript策略模式

JavaScript策略模式1什么是策略模式2实现一个基础的策略模式3Javascript中策略模式4使用策略模式实现缓动动画5使用策略模式实现表单校验1什么是策略模式策略模式(StrategyPattern)是一种行为型设计模式,它定义了一系列算法,将每个算法都封装起来,并且使它们可以相互替换。策略模式让算法独立于使

Java的Socket通信的断网重连的正确写法

Java的Socket通信的断网重连的正确写法Socket通信的断网重连介绍客户端与服务端源码演示截图本地演示服务器演示演示截图总结Socket通信的断网重连介绍针对于已经建立通信的客户端与服务器,当客户端与服务器因为网络问题导致网络不通而断开连接了或者由于服务器端的服务被突然停掉,而客户端进行的一种尝试重新建立连接的

热文推荐