C++&QT day7

2023-09-14 21:27:49

仿照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;
}




思维导图:

更多推荐

《C++标准库第2版》3.2 虽旧犹新的语言特性 笔记

3.2虽旧犹新的语言特性非类型模板参数1.除了类型参数之外,我们也可以为template使用nontypeparamatter.2.非类型参数看作是template类型的一部分bitset<32>flags32;bitset<50>flags50;//这两个看作是两个不同类型的template模板参数默认值classt

详解junit

目录1.概述2.断言3.常用注解3.1.@Test3.2.@Before3.3.@After3.4.@BeforeClass3.5.@AfterClass4.异常测试5.超时测试6.参数化测试1.概述什么是单元测试:单元测试,是针对最小的功能单元编写测试代码,在JAVA中最小的功能单元是方法,单元测试针对JAVA就是单

Blender批量修改名称

假如在Blender里按顺序添加了多个mesh,名字后缀按照数字1,2,3…编号,此时又要插入一个新的mesh,那么这个mesh之后的其它mesh名字都要加1,此时该怎么办呢?比较简单的办法是把新mesh后面的mesh名称一个一个手动加1,如果数量少还可以,如果很多就有点浪费时间了。Blender自身也提供了批量修改的

多旋翼无人机组合导航系统-多源信息融合算法(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。⛳️座右铭:行百里者,半于九十。📋📋📋本文目录如下:🎁🎁🎁目录💥1概述📚2运行结果🎉3参考文献🌈4Matlab代码实现💥1概述多旋翼无人机已被广泛应用于军事与民用领域。导航系统

C++中string对象之间比较、char*之间比较

#include<cstring>//char*使用strcmp#include<string>//string使用compare#include<iostream>usingnamespacestd;intmain(){stringstringStr1="42";stringstringStr2="42";strin

《golang设计模式》第二部分·结构型模式-05-门面模式Facade)

文章目录1.概述1.1角色1.2类图2.代码示例2.1设计2.2代码2.2类图1.概述门面(Facade)向客户端提供使用子系统的统一接口,用于简化客户端使用子系统的操作。1.1角色门面角色(Facade)客户端可以调用的接口或方法此角色知晓系统的所有功能和责任一般情况下,该角色没有实际业务逻辑,只是一个委托类。子系统

蓝桥杯每日一题2023.9.16

蓝桥杯2022年第十三届省赛真题-X进制减法-C语言网(dotcpp.com)题目描述进制规定了数字在数位上逢几进一。X进制是一种很神奇的进制,因为其每一数位的进制并不固定!例如说某种X进制数,最低数位为二进制,第二数位为十进制,第三数位为八进制,则X进制数321转换为十进制数为65。现在有两个X进制表示的整数A和B,

基于NAudio实现录制声卡声音

之前的文章《测试.net开源音频库NAudio》中介绍了基于NAudio模块中的WaveInEvent和WaveFileWriter类实现基本的录音功能,但存在一个问题:本来想录制视频中的声音,但录音过程中会把麦克风中的杂音(挪动物品的声音、说话声音等)一并录进去。NAudio模块中提供有WasapiLoopbackC

代理IP与Socks5代理:跨界电商智能爬虫与出海之道

跨界电商正成为全球市场的关键驱动力,而代理IP和Socks5代理则为其提供了技术支持。本文将深入研究这两种代理技术在跨界电商、爬虫和出海战略中的重要作用。引言:介绍跨界电商的崛起和全球化趋势。引出代理IP和Socks5代理的重要性以及本文的主题。第一部分:代理IP和Socks5代理的基础知识代理IP和Socks5代理的

文心一言 VS 讯飞星火 VS chatgpt (97)-- 算法导论9.3 3题

三、用go语言,假设所有元素都是互异的,说明在最坏情况下,如何才能使快速排序的运行时间为O(nlgn)。文心一言:快速排序是一种基于分治策略的排序算法,其平均时间复杂度为O(nlgn)。在最坏情况下,快速排序的时间复杂度为O(n^2),这是因为当输入数组已经排序或接近排序时,快速排序的性能会退化。为了使快速排序在最坏情

Python的协程异步IO(asyncio)详解

一、协程简介1.1定义协程不是系统级线程,很多时候协程被称为“轻量级线程”、“微线程”、“纤程(fiber)”等。简单来说可以认为协程是线程里不同的函数,这些函数之间可以相互快速切换。协程和用户态线程非常接近,用户态线程之间的切换不需要陷入内核,但部分操作系统中用户态线程的切换需要内核态线程的辅助。协程是编程语言(或者

热文推荐