返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++中STL vector的模拟实现示例
  • 354
分享到

C++中STL vector的模拟实现示例

2023-06-14 23:06:39 354人浏览 独家记忆
摘要

这篇文章主要介绍c++中STL vector的模拟实现示例,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1. vector的介绍和使用vector是表示可变大小数组的序列容器。就像数组一样,vector也采用的连续存

这篇文章主要介绍c++中STL vector的模拟实现示例,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

1. vector的介绍和使用

  • vector是表示可变大小数组的序列容器

  • 就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自动处理。

  • 本质讲,vector使用动态分配数组来存储它的元素。当新元素插入时候,这个数组需要被重新分配大小为了增加存储空间。其做法是,分配一个新的数组,然后将全部元素移到这个数组。就时间而言,这是一个相对代价高的任务,因为每当一个新的元素加入到容器的时候,vector并不会每次都重新分配大小。

  • vector分配空间策略:vector会分配一些额外的空间以适应可能的增长,因为存储空间比实际需要的存储空间更大。不同的库采用不同的策略权衡空间的使用和重新分配。但是无论如何,重新分配都应该是对数增长的间隔大小,以至于在末尾插入一个元素的时候是在常数时间的复杂度完成的。

  • 因此,vector占用了更多的存储空间,为了获得管理存储空间的能力,并且以一种有效的方式动态增长。

  • 与其它动态序列容器相比(deques, lists and forward_lists), vector在访问元素的时候更加高效,在末尾添加和删除元素相对高效。对于其它不在末尾的删除和插入操作,效率更低。比起lists和forward_lists统一的迭代器和引用更好。

更为详细的可以查看vector文档介绍。

2. vector的模拟实现

vector的嵌套型别定义

typedef _Ty         value_type;typedef value_type* iterator;typedef value_type& reference;typedef size_t      size_type;

vector的成员变量

private:        iterator _start;        iterator _last;        iterator _end;

2.1 vector构造函数和拷贝构造函数

vector():_start(nullptr),_last(nullptr),_end(nullptr){}vector(size_type n,const _Ty& value):_start(nullptr),_last(nullptr),_end(nullptr){     insert(n,value);}vector(iterator f,iterator l):_start(nullptr),_last(nullptr),_end(nullptr){     insert(f,l);}   vector(const vector<int>& iv){        reserve(iv.capacity());        iterator it = begin();        iterator vit = iv.end();        while (vit != iv.begin())        {              *it++ = *vit--;             }}

2.2 insert函数和eraser函数

iterator insert(iterator pos,const _Ty& value){    //1.当size()==capacity()时,表明vector已满,再进行插入前需要进行扩容    if(size()== capacity())    {        size_type oldpos = pos - begin();        //这里需要防止一种情况:若vector为空的时候,他的capacity为0,这个时候给他直接扩容2倍是行不通的,        //因为2*0 = 0,因此就需要进行判断         size_type newcapacity = (capacity() == 0)? 1 : 2*capacity();        reserve(newcapacity);        //这里空间发生了变化,pos迭代器会失效,因此需要重新对pos进行设置        //reserve不会使vector的成员变量失效        pos = begin() + oldpos;    }    //2.当size() < capacity()时,表明vector未满,插入直接在pos的位置进行插入    //需要注意的是插入是在pos指向的位置进行插入,并且插入需要挪动数据,    //将pos位置之后的数据全部向后挪动一个,为防止元素被改写,则需要从后向前进行挪动    iterator tail = _last;    while(tail > pos)    {        *tail = *(tail-1);        --tail;    }    //这里要注意的是挪动数据时,因为没有对pos位置进行操作,所以pos位置的迭代器并没有失效,    //但是pos位置之后的迭代器全部失效了,但在这里并没有关系,我们并不会用到那些迭代器    *pos = value;    //插入完之后,一定要对_last指针+1,因为全部向后挪动了一个元素    ++_last;    return pos;}void insert(size_type n,const _Ty& value){    for(int i = 0;i < n; ++i)    {        insert(end(),value);    }}void insert(iterator f,iterator l){    while(f!=l)    {        insert(end(),*f);        ++f;    }}iterator erase(iterator pos){    assert(pos >= _start || pos < _last);    //1.删除pos位置的元素,就是将[pos,end()]这个区间向前挪动一个即可    iterator it = pos + 1;    while(it != _last)    {        *(it-1) = *(it);        ++it;    }    --_last;    return pos;}

2.3 reserve函数和resize函数

void reserve(size_type n){    //若 n 的值大于vector的容量,则开辟空间    //若 n 的值小于等于,则不进行任何操作    if(n > capacity())    {        //1.新开辟一个空间        size_type oldSize = size();        _Ty* newVector = new _Ty[n];        //2.将原空间的数值赋值到新空间        if(_start)        {            //注意:这里不能使用memcpy,因为memcpy是一个浅拷贝。            //memcpy(newVector,_start,sizeof(_Ty)*size());            for(size_type i = 0; i < oldSize; ++i)            {                newVector[i] = _start[i];            }        }        //3.改变三个指针的指向        //这里直接重新给三个成员进行赋值,所以调用reserve()函数不用担心迭代器失效的问题        _start = newVector;        _last = _start + oldSize;        _end = _start + n;    }}void resize(size_type n,const _Ty& value = _Ty()){    //1.如果n的值小于等于size()的时候,则只需要将_last的指针往前移动即可    if(n <= size())    {        _last = _start + n;        return;    }    //2.如果n的值大于capacity()的时候,则需调用reserve()函数,重新设置容量大小    if(n > capacity())    {        reserve(n);    }    //若当n的值大于size()而小于capacity()的时候,只需将_last的指针往后移即可    iterator it = _last;    _last = _start + n;    while(it != _last)    {        *it = value;        ++it;    }    //resize()函数也不需要担心迭代器失效的问题}

2.4 push_back函数和pop_back函数

void push_back(const _Ty& value){    insert(end(),value);}void pop_back(){    erase(end()-1);}

2.5 begin函数和end函数

iterator begin()const{    return _start;}iterator end() const{    return _last;}

2.6 size函数、capacity函数

size_type size(){    return end()-begin();}size_type capacity()const{    return _end-begin();}

2.7 empty函数和operator[]重载

bool empty()const{    return end() == begin();}reference operator[](size_type n){    return *(begin() + n);}

2.8 完整代码和相应测试

#include <iOStream>#include <assert.h>using namespace std;namespace mytest{    template<class _Ty>    class vector    {        public:            typedef _Ty         value_type;            typedef value_type* iterator;            typedef value_type& reference;            typedef size_t      size_type;        public:            iterator begin()const            {                return _start;            }            iterator end() const            {                return _last;            }            size_type size()            {                return end()-begin();            }            size_type capacity()const            {                return _end-begin();            }            bool empty()const            {                return end() == begin();            }            reference operator[](size_type n)            {               return *(begin() + n);             }        public:            vector():_start(nullptr),_last(nullptr),_end(nullptr)            {}            vector(size_type n,const _Ty& value):_start(nullptr),_last(nullptr),_end(nullptr)            {                insert(n,value);            }            vector(iterator f,iterator l):_start(nullptr),_last(nullptr),_end(nullptr)            {                insert(f,l);            }               vector(const vector<int>& iv)            {                reserve(iv.capacity());                iterator it = begin();                iterator vit = iv.end();                while (vit != iv.begin())                {                    *it++ = *vit--;                     }            }        public:            void reserve(size_type n)            {                //若 n 的值大于vector的容量,则开辟空间                //若 n 的值小于等于,则不进行任何操作                if(n > capacity())                {                    //1.新开辟一个空间                    size_type oldSize = size();                    _Ty* newVector = new _Ty[n];                    //2.将原空间的数值赋值到新空间                    if(_start)                    {                        //注意:这里不能使用memcpy,因为memcpy是一个浅拷贝。                        //memcpy(newVector,_start,sizeof(_Ty)*size());                        for(size_type i = 0; i < oldSize; ++i)                        {                            newVector[i] = _start[i];                        }                    }                    //3.改变三个指针的指向                    //这里直接重新给三个成员进行赋值,所以调用reserve()函数不用担心迭代器失效的问题                    _start = newVector;                    _last = _start + oldSize;                    _end = _start + n;                }            }            void resize(size_type n,const _Ty& value = _Ty())            {                //1.如果n的值小于等于size()的时候,则只需要将_last的指针往前移动即可                if(n <= size())                {                    _last = _start + n;                    return;                }                //2.如果n的值大于capacity()的时候,则需调用reserve()函数,重新设置容量大小                if(n > capacity())                {                    reserve(n);                }                //若当n的值大于size()而小于capacity()的时候,只需将_last的指针往后移即可                                iterator it = _last;                _last = _start + n;                while(it != _last)                {                    *it = value;                    ++it;                }                //resize()函数也不需要担心迭代器失效的问题            }            void push_back(const _Ty& value)            {                insert(end(),value);            }            void pop_back()            {                erase(end()-1);            }                        iterator insert(iterator pos,const _Ty& value)            {                //1.当size()==capacity()时,表明vector已满,再进行插入前需要进行扩容                if(size()== capacity())                {                    size_type oldpos = pos - begin();                    //这里需要防止一种情况:若vector为空的时候,他的capacity为0,                    //这个时候给他直接扩容2倍是行不通的,因为2*0 = 0,因此就需要进行判断                     size_type newcapacity = (capacity() == 0)? 1 : 2*capacity();                    reserve(newcapacity);                    //这里空间发生了变化,pos迭代器会失效,因此需要重新对pos进行设置                    //reserve不会使vector的成员变量失效                    pos = begin() + oldpos;                }                //2.当size() < capacity()时,表明vector未满,插入直接在pos的位置进行插入                //需要注意的是插入是在pos指向的位置进行插入,并且插入需要挪动数据,                //将pos位置之后的数据全部向后挪动一个,为防止元素被改写,则需要从后向前进行挪动                iterator tail = _last;                while(tail > pos)                {                    *tail = *(tail-1);                    --tail;                }                //这里要注意的是挪动数据时,因为没有对pos位置进行操作,所以pos位置的迭代器并没有失效,                //但是pos位置之后的迭代器全部失效了,但在这里并没有关系,我们并不会用到那些迭代器               *pos = value;               //插入完之后,一定要对_last指针+1,因为全部向后挪动了一个元素               ++_last;               return pos;            }            void insert(size_type n,const _Ty& value)            {                for(int i = 0;i < n; ++i)                {                    insert(end(),value);                }            }            void insert(iterator f,iterator l)            {                while(f!=l)                {                    insert(end(),*f);                    ++f;                }            }            iterator erase(iterator pos)            {                assert(pos >= _start || pos < _last);                //1.删除pos位置的元素,就是将[pos,end()]这个区间向前挪动一个即可                iterator it = pos + 1;                while(it != _last)                {                    *(it-1) = *(it);                    ++it;                }                --_last;                return pos;            }                     private:            iterator _start;            iterator _last;            iterator _end;    };};void Test1(){    mytest::vector<int> iv;    cout << "iv.size() = " << iv.size() << endl;    cout << "iv.capacity() = " << iv.capacity() << endl;    iv.push_back(1);    iv.push_back(2);    iv.push_back(3);    iv.push_back(4);    cout << "iv.size() = " << iv.size() << endl;    cout << "iv.capacity() = " << iv.capacity() << endl;    mytest::vector<int>::iterator it = iv.begin();    while(it != iv.end())    {        cout << *it << " ";        ++it;    }    cout << endl;    iv.pop_back();    iv.pop_back();    it = iv.begin();    while(it != iv.end())    {        cout << *it << " ";        ++it;    }    cout << endl;}void Test2(){    mytest::vector<int> iv(10,2);     mytest::vector<int>::iterator it = iv.begin();    while(it != iv.end())    {        cout << *it << " ";        ++it;    }    cout << endl;}void Test3(){    int ar[] = {1,2,3,3,4,5};    mytest::vector<int> iv(ar,ar+6);    mytest::vector<int>::iterator it = iv.begin();    while(it != iv.end())    {        cout << *it << " ";        ++it;    }    cout << endl;}int main(){//    Test1();//    Test2();    Test3();    return 0;}

以上是“C++中STL vector的模拟实现示例”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注编程网其他教程频道!

--结束END--

本文标题: C++中STL vector的模拟实现示例

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

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

猜你喜欢
  • C++中STL vector的模拟实现示例
    这篇文章主要介绍C++中STL vector的模拟实现示例,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1. vector的介绍和使用vector是表示可变大小数组的序列容器。就像数组一样,vector也采用的连续存...
    99+
    2023-06-14
  • C++ STL vector的模拟实现
    1. vector的介绍和使用 vector是表示可变大小数组的序列容器。 就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对v...
    99+
    2024-04-02
  • C++  STL _ Vector使用及模拟实现
    目录1.Vector的介绍1.1 Vector的介绍2.Vector的使用2.1 vector的定义2.2 vector 迭代器的使用 2.3 vector的空间增长问题3...
    99+
    2024-04-02
  • c++中vector模拟实现的示例分析
    这篇文章将为大家详细讲解有关c++中vector模拟实现的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、vector是什么?vector是表示可变大小数组的序列容器,它也采用连续存储空间来存储...
    99+
    2023-06-14
  • C++模拟实现vector的示例代码
    目录1.前言2.vector介绍3.vector模拟实现3.1 迭代器接口3.2 vector元素操作3. 3 构造与析构1.前言 大家在学习C++的时候一定会学到STL(标准模板库...
    99+
    2024-04-02
  • C++中vector的模拟实现实例详解
    目录vector接口总览 默认成员函数 构造函数 拷贝构造 赋值重载 析构函数 迭代器相关函数 begin和end 容量相关函数 size和capacity reserve resi...
    99+
    2024-04-02
  • C++模拟实现vector示例代码图文讲解
    目录vector的模拟实现使用memcpy拷贝问题vector的模拟实现 #include <iostream> using namespace std; #includ...
    99+
    2023-02-27
    C++ vector模拟实现 C++ vector模拟
  • C++中如何模拟实现vector
    这篇文章给大家分享的是有关C++中如何模拟实现vector的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。vector接口总览namespace nzb{//模拟实现vectortemplate<c...
    99+
    2023-06-25
  • C++模拟实现vector的方法
    今天小编给大家分享一下C++模拟实现vector的方法的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。1. 模拟实现vecto...
    99+
    2023-07-02
  • c++中vector的使用和模拟实现
    一、接口介绍 1、插入数据 void push_back(const T& x) 在当前vector尾部插入x,如果容量不够扩大二倍。 iterator insert(it...
    99+
    2024-04-02
  • C++ STL容器中红黑树部分模拟实现的示例分析
    这篇文章主要介绍了C++ STL容器中红黑树部分模拟实现的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、红黑树的概念红黑树(Red Black Tree...
    99+
    2023-06-21
  • C++STL中vector模板类是什么
    小编给大家分享一下C++STL中vector模板类是什么,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!vector模板类创建vector对象,遍历元素vector...
    99+
    2023-06-29
  • 【C++进阶(二)】STL大法--vector的深度剖析以及模拟实现
    💓博主CSDN主页:杭电码农-NEO💓   ⏩专栏分类:C++从入门到精通⏪   🚚代码仓库:NEO的学习日记🚚   ...
    99+
    2023-09-06
    c++ java 开发语言
  • 详解C++ STL模拟实现list
    目录list 概述接口总览list 的节点默认成员函数默认构造函数析构函数拷贝构造函数复制赋值函数list 的迭代器构造函数operator==operator!=operator*...
    99+
    2023-01-11
    C++ STL实现list C++ STL list
  • 详解C++STL模拟实现forward_list
    目录forward_list 概述接口总览forward_list 的节点默认成员函数默认构造函数析构函数forward_list 的迭代器构造函数operator==operato...
    99+
    2023-01-13
    C++ STL实现forward_list C++ STL forward_list
  • c++ vector模拟实现的全过程
    一、vector是什么? vector是表示可变大小数组的序列容器,它也采用连续存储空间来存储元素,因此可以采用下标对vector的元素进行访问,它的大小是动态改变的,vector...
    99+
    2024-04-02
  • C++ vector类的模拟实现方法
    vector和string虽然底层都是通过顺序表来实现的,但是他们利用顺序表的方式不同,string是指定好了类型,通过使用顺序表来存储并对数据进行操作,而vector是利用了C++...
    99+
    2024-04-02
  • C++实现STL容器的示例
    各大容器的特点: 1.可以用下标访问的容器有(既可以插入也可以赋值):vector、deque、map; 特别要注意一下,vector和deque如果没有预先指定大小,是不能用下标法...
    99+
    2024-04-02
  • C++模拟实现vector代码分析
    本篇内容主要讲解“C++模拟实现vector代码分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++模拟实现vector代码分析”吧!vector的模拟实现#include <...
    99+
    2023-07-05
  • C++模拟实现vector流程详解
    目录模拟vector总结模拟vector 我们可以通过模板实现类似vector的类。我们实现一个StrVecTemp类,其内部通过allocator开辟空间,存储的类型用T来表示,T...
    99+
    2022-11-13
    C++ vector容器 C++ vector
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作