• 【C++】--模拟实现vector



    vector和我们学数据结构时候的顺序表差不多,不过STL库里面的vector给我们提供了很多的接口函数,十分方便。对于各接口的调用这里就不详细讲解了,用到的时候不熟悉可以去官网查一下。这篇文章主要讲讲 个人对vector模拟实现的方法

    image-20221124160305301

    Constructors(构造函数)

    vector是一个模板类,可以存储不同类型的数据。先来看看官方的几种构造法方法

    image-20221124160734864

    因为vector是一个模板类,所以在定义类时要用模板的格式。在vector中可以简单的定义三个类变量,全部用模板类型的指针类型

    iterator _start;//首地址
    iterator _finish;//最后一位有效数据的后一位地址
    iterator _endofstorage;//容量的最后一位地址

    template<class T>
    	class myvector {
       
    	public:
    		typedef T* iterator;
    		typedef const T* const_iterator;
            
    	private:
    		iterator _start;//首地址
    		iterator _finish;//最后一位有效数据地址
    		iterator _endofstorage;//容量的最后一位地址
    	};
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    myvector()

    定义好变量后,先实现一个无参的构造函数。因为变量都是指针类型,所以一开始我们可以将它们初始化为nullptr

    myvector()
        :_start(nullptr)
        , _finish(nullptr)
        ,_endofstorage(nullptr)
    {
       }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    myvector(int n, const T& val = T())

    再来实现一个跟库里面一样的,可以指定对象开辟的空间大小,并把指定值填入每一个空间中

    myvector(int n, const T& val = T()) 
        :_start(nullptr)
        , _finish(nullptr)
        , _endofstorage(nullptr)
    {
       
        reserve(n);
        for (int i = 0; i < n; i++)
        push_back(val);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    push_back的实现下面再将。

    注意:这个的缺省值不能用0或者" ",因为类型T没有确定,有可能会是我们自定义的类型,所以缺省值要使用T类型的默认初始值。参数中的n为什么不用size_t类型呢,下面会谈到

    myvector(InputIterator first, InputIterator last)

    接下来库里面的第三个构造函数,指定一段区间,并将这段区间的所有数值赋值到对象中。因为是一段区间,所以参数传的是指针,但是由于类型没有确定,所以要使用模板函数

    template <class InputIterator>
    myvector(InputIterator first, InputIterator last)
        :_start(nullptr)
        , _finish(nullptr)
        , _endofstorage(nullptr)
    {
       
        while (first != last) {
       
            push_back(*first);
            first++;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    为什么上面讲的第二个构造不使用size_t类型呢,就是因为第三个区间的构造传的参数是指针类型,如果第二个参数使用的是size_t类型,那么当我们构造传参时,编译器就不知道去匹配哪一个构造函数了。所以为了避免冲突,第二个构造我们使用int类型参数。

    拷贝构造

    接下来实现拷贝构造函数,因为有了上面的区间构造函数后,我们只需要创建一个临时的对象,然后和原对象交换一下后就可以了。需要注意的是,交换的时候要将地址交换才不会出现野指针的情况

    myvector(const myvector<T>& v)
        :_start(nullptr)
        , _finish(nullptr)
        , _endofstorage(nullptr)
    {
       
        myvector<int> tmp(v.begin(), v.end());
        swap(tmp);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    交换函数

    交换地址就可以直接实现了

    void swap(myvector<T>& v) {
       
        std::swap(_start, v._start);
        std::swap
    • 1
    • 2
    • 3
  • 相关阅读:
    如何让你的量化交易系统具有概率优势,具有正向收益预期呢?
    工业交换机选用技巧
    centos oracle11g开启归档模式
    KubeSphere 网关的设计与实现(解读)
    .NET异步编程模式(四)-TAP
    通过汇编理解cortex-m3:第0章
    “山大地纬杯”第十二届山东省ICPC大学生程序设计竞赛(正式赛)
    P27 含并行连结的网络 GoogLeNet / Inception V3
    Nginx配置虚拟主机
    【逗老师的无线电】MMDVM添加4G网卡之后变身4G路由器
  • 原文地址:https://blog.csdn.net/weixin_52563203/article/details/128028126