C++day7

2023-09-14 21:25:20

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

#include <iostream>

using namespace std;

template<typename T>
class my_vector
{

    int size;//可存储的容量大小
    int num;//当前存储的元素个数
    T* data;//存储数据的空间地址

public:
    //无参构造函数
    my_vector();
    //有参构造函数
    my_vector(int n, const T m);
    //析构函数
    ~my_vector();
    //拷贝构造
    my_vector(const my_vector &other);
    //返回当前的容器大小
    int get_capacity();
    //获取容器中的元素个数
    int get_size();
    //判空函数
    bool empty();
    //添加函数
    void push_back(const T &val);
    //向容器中赋值
    void assign(int n,const T &val);
    //访问容器中的元素
    T& at(int loc);
    //清空容器中的元素
    void clear();
    //删除最后一个元素
    void pop_back();
    //返回起始位置的引用
    T& front();
    //返回最后一个位置的引用
    T& back();
    //返回第一个位置的迭代器
    T* begin();
    //返回末尾下一个位置的迭代器
    T* end();
    //任意插入
    T* insert(T* p, const T& n);
    //遍历
    void show();
};
int main()
{

   my_vector<int> s1;
   s1.assign(7,1);
   cout<<"最大容量"<<s1.get_capacity()<<endl;
   cout<<"最后一个元素 "<<s1.at(6)<<endl;
   s1.insert(s1.end(),4);
   cout<<"最后一个元素 "<<s1.back()<<endl;
   cout<<"共有元素"<<s1.get_size()<<endl;
   cout<<"最后一个元素 "<<s1.at(8)<<endl;
   s1.show();
   cout<<"最大容量"<<s1.get_capacity()<<endl;
   s1.pop_back();
   s1.show();
    return 0;
}

//无参构造
template<typename T>
my_vector<T>::my_vector()
{
    size=6;
    num=0;
    data = new T[6];
}

//有参构造
template<typename T>
my_vector<T>::my_vector(int n, const T m)
{
    size = n;
    num = n;
    data = new T[n];
    for(int i=0;i<n;i++)
    {
        data[i]= m;
    }
}

template<typename T>
my_vector<T>::~my_vector()
{
    delete []data;
}

//拷贝构造
template<typename T>
my_vector<T>::my_vector(const my_vector &other)
{
    size = other.size;
    num  = other.num;
    data = new T[size];

    for(int i=0;i<other.num;i++)
    {
        data[i] = other.data[i];
    }
}

//当前容器的大小
template<typename T>
int my_vector<T>::get_capacity()
{
    return size;
}

template<typename T>
int my_vector<T>::get_size()
{
    return num;
}

//判空函数
template<typename T>
bool my_vector<T>::empty()
{
    if(0 == num)
    {
        return true;
    }
    else
        return false;
}

//添加函数
template<typename T>
void my_vector<T>::push_back(const T &val)
{
    if(num<size)
    {
        data[num] = val;
        num++;
    }
    else
    {

        T *temp = new T[2*size];
        size = 2*size;
        for(int i=0;i<num;i++)
        {
            temp[i] = data[i];
        }
        delete []data;//释放旧的空间
        data = temp;//指向新的空间
        temp = nullptr;
        data[num] = val;
        num++;

    }
}

//向容器中赋值
template<typename T>
void my_vector<T>::assign(int n, const T &val)
{
    //判断赋值的个数是否超过最大容量
    if(n>size)
    {

        delete [] data;
        data = nullptr;
        data = new  T [n];
        size = n;
        num = n;
        //赋值
        for(int i=0;i<n;i++)
        {
            data[i] = val;
        }
    }
    else
    {
        num=n;
        for(int i=0;i<n;i++)
        {
            data[i] = val;
        }
    }
}

//访问元素
template<typename T>
T& my_vector<T>::at(int loc)
{
    if(loc > num || loc < 0)
    {
        throw T(1);//越界异常
    }
    else
    {
        return data[loc-1];
    }
}

//清空所有元素
template<typename T>
void my_vector<T>::clear()
{
    while (!empty())
    {
        pop_back();
    }

}

//删除末尾元素
template<typename T>
void my_vector<T>::pop_back()
{
    if(!empty())
    {
        data[num-1] = 0;
         num--;
    }
    else
        return ;
}

//返回第一个位置的引用
template<typename T>
T &my_vector<T>::front()
{
    return data[0];
}

//返回最后一个位置的引用
template<typename T>
T &my_vector<T>::back()
{
    return data[num-1];
}

//返回第一个位置的迭代器
template<typename T>
T *my_vector<T>::begin()
{
    return &data[0];
}

//返回末尾下一个位置的迭代器
template<typename T>
T *my_vector<T>::end()
{
    return &data[num];
}

//任意插入
template<typename T>
T *my_vector<T>::insert(T *p, const T &n)
{
    int j = 0;
      while(&data[0]+j != p) //寻找输入的是第几个数据的地址
      {
          j++;
      }
      if(num == size) //判断当前是否已满
      {
          int i = 0;
          T* data_new = new T[size*2];  //二倍扩容
          size = size * 2;
          while(i < num)       //将旧区的数据内容赋给新区
          {
              data_new[i] = data[i];
              i++;
          }
          delete []data;          //释放旧区
          data = data_new;        //指向新区
          data_new = nullptr;     //新指针置空
          //将指定位置之后的数据全都后移一位
          for(int k = num,i = j;i < num;i++,k--)
          {
                  data[k] = data[k-1];
          }
          data[j] = n;     //插入元素
          num++;               //存储数量加1
          return &data[j];
      }
      else if(num < size)
      {
          //将指定位置之后的数据全都后移一位
          for(int k = num,i = j;i < num;i++,k--)
          {
                  data[k] = data[k-1];
          }
          data[j] = n;     //插入元素
          num++;               //存储数量加1
          return &data[j];
      }
}

//遍历
template<typename T>
void my_vector<T>::show()
{
    int i = 0;
    for(;i < num;i++)
    {
        cout << data[i] << "\t";
    }
       cout << endl;
}

 

更多推荐

docker容器的设置本地时间(/etc/localtime)和本地时区(/etc/timezone)

本地时区的修改一般情况下,我们启动docker容器时指定了环境变量:-eTZ:=Asia/Ho_Chi_Minh,容器内的时区就会变成东八区,某些软件则会读取该环境变量作为其使用的时区,该环境变量相当于"残缺版"的命令:echo'Asia/Ho_Chi_Minh'>/etc/timezone为什么说残缺版,继续往下看。

STM32 ~ GPIO不同模式之间的区别与实现原理

GPIO全称GeneralPurposeInputOutput,即通用输入/输出。其实GPIO的本质就是芯片的一个引脚,通常在ARM中所有的I/O都是通用的。不过,由于每个开发板上都会设计不同的外围电路,这就造成了GPIO的功能可能有所不同。大部分GPIO都是有复用功能的,比如有些GPIO可能是串口的TX或RX,也可能

【音视频】ffplay源码解析-PacketQueue队列

包队列架构位置对应结构体源码MyAVPacketListtypedefstructMyAVPacketList{AVPacketpkt;//解封装后的数据structMyAVPacketList*next;//下一个节点intserial;//播放序列}MyAVPacketList;PacketQueuetypedef

面试官:Javscript数组的常用方法有哪些?

🎬岸边的风:个人主页🔥个人专栏:《VUE》《javaScript》⛺️生活的理想,就是为了理想的生活!目录一、操作方法增push()unshift()spliceconcat()删pop()shift()splice()slice()改splice()查indexOf()includes()find()二、排序方法

强化学习:实现了基于蒙特卡洛树和策略价值网络的深度强化学习五子棋(含码源)

【强化学习原理+项目专栏】必看系列:单智能体、多智能体算法原理+项目实战、相关技巧(调参、画图等、趣味项目实现、学术应用项目实现专栏详细介绍:【强化学习原理+项目专栏】必看系列:单智能体、多智能体算法原理+项目实战、相关技巧(调参、画图等、趣味项目实现、学术应用项目实现对于深度强化学习这块规划为:基础单智能算法教学(g

STM32F4X UCOSIII 信号量

STM32F4XUCOSIII信号量信号量概念信号量工作机制停车场问题UCOSIII信号量工作机制信号量常用API信号量创建信号量删除释放信号量获取信号量UCOSIII信号量例程在以往的裸机编程中,如果我们需要判断某个事件是否已经发生,通常会使用一个标志位来进行判断,当事件已经发生时,就将该标志位置1,否则就将该标志位

pytorch 入门(一)

本文为🔗小白入门Pytorch内部限免文章参考本文所写记录性文章,请在文章开头注明以下内容,复制粘贴即可⬇️基础版模板⬇️🐳我正在和鲸社区参加“小白入门Pytorch”https://www.heywhale.com/home/activity/detail/64e2ce39e585b8f50bf6c2e7,以下是

frame切换/窗口切换/选择框

frame获取焦点我们操作一个东西就要获得他的焦点才行!!!!例子:fromseleniumimportwebdriverfromselenium.webdriver.common.byimportBywd=webdriver.Chrome()wd.get('https://cdn2.byhy.net/files/se

DevOps与CI/CD常见面试问题汇总

01您能告诉我们DevOps和Agile(敏捷)之间的根本区别吗?答:尽管DevOps与敏捷方法(这是最流行的SDLC[SoftwareDevelopmentLifeCycle]方法之一)有一些相似之处,但两者在软件开发方面都是根本不同的方法。以下是两者之间的各种基本差异:敏捷方法敏捷方法适用于敏捷中的开发同时敏捷方法

分享基于SringBoot足球训练俱乐部系统Python训练打卡系统(源码+调试+lw)

💕💕作者:计算机源码社💕💕个人简介:本人七年开发经验,擅长Java、Python、PHP、.NET、微信小程序、爬虫、大数据等,大家有这一块的问题可以一起交流!💕💕学习资料、程序开发、技术解答、文档报告💕💕如需要源码,可以扫取文章下方二维码联系咨询💕💕JavaWeb项目💕💕微信小程序项目💕💕

一线大厂Redis高并发缓存架构实战与性能优化

多级缓存架构缓存设计缓存穿透缓存穿透是指查询一个根本不存在的数据,缓存层和存储层都不会命中,通常出于容错的考虑,如果从存储层查不到数据则不写入缓存层。缓存穿透将导致不存在的数据每次请求都要到存储层去查询,失去了缓存保护后端存储的意义。造成缓存穿透的基本原因有两个:第一,自身业务代码或者数据出现问题。第二,一些恶意攻击、

热文推荐