【C++】vector容器的模拟实现

这篇具有很好参考价值的文章主要介绍了【C++】vector容器的模拟实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一,框架设计

二,构造函数

三,析构函数

四,赋值运算符

五,容器接口的实现

1,迭代器实现

2,“ [] ”运算符的实现

3,swap交换和resize重设大小

4,insert插入和erase删除


介绍:

        本文,我们重点实现vector容器的用法,这里要注意的是vector容器可以接纳任意类型,所以,在实现的时候需使用模板来控制。模拟实现vector重点还要放在构造、析构和赋值运算符重载。


一,框架设计

        vector容器设置中,由于需要接纳各种类型,因此,在框架设计中需要使用模板。除此之外,要想访问未知类型数据,需要使用迭代器来访问。这里,我们设置三个迭代器,分别指向数据块开始位置、有效数据的末尾、存储容量的末尾。

template<class T>
class vector
{
public:
    typedef T* iterator;         
 //数据迭代器
    typedef const T* const_iterator;   //常量迭代器
private:
    iterator _start;                 
// 指向数据块的开始
    iterator _finish;                // 指向有效数据的尾
    iterator _endOfStorage;  // 指向存储容量的尾
};


二,构造函数

        在使用构造函数之前,我们首先要考虑基础的算法设置以方便使用:reverse扩容、capacity容器容量、size容器大小、push_back增添元素、pop_back删除元素。

//获取容器大小

size_t size() const
{
    return _finish - _start;
}

//获取容器容量
size_t capacity() const
{
    return _endOfStorage - _start;
}

//容器扩容

void reserve(size_t n)
{
    if (n > capacity())    //只能增容不能缩小
    {
        int newsize = size();
        T* tem = new T[n];
        memcpy(tem, _start, sizeof(T) * newsize);
        if (_start)
        {
            delete[] _start;
        }
        _start = tem;
        _finish = _start + newsize;
        _endOfStorage = _start + n;
    }
}

//增添数据

void push_back(const T& x)
{
    if (capacity() == size())   //这里要注意容量是否够用
    {
        int newcapacity = capacity() == 0 ? 4 : 2 * capacity();
        reserve(newcapacity);
    }
    int newsize = size();
    _start[newsize] = x;
    _finish++;
}

//删除数据

void pop_back()
{
    assert(size() > 0);   //这里要注意容器是否为空
    _finish--;
}

普通构造函数      

        首先,我们先实现无任何传入值的构造函数。这种情况只需初始化容器的各种数据即可,不需要做任何增添。

vector()
{
    _start = _finish = _endOfStorage = nullptr;   //直接将数据设为空
}

        第二种构造方式这里模拟实现构造n个数据,如:vector<int>v(5,8)初始化为5个8。

//T()表示T类型的构造函数,即上面第一种的构造函数实现 

vector(int n, const T& value = T())  
{
    reserve(n);      //这里要先进行扩容
    for (int i = 0; i < n; i++)
    {
        push_back(value);  
    }
}

        第三种构造方式模拟实现迭代器的方式进行构造。因为数据类型未知,所以这里还需要使用模板。

//这里迭代器要使用模板

template<class InputIterator>   

//first指向开始位置,last指向终点的下一位
vector(InputIterator first, InputIterator last)  
{
    int newsize = last - first;  
    reserve(newsize);
    for (int i = 0; i < newsize; i++)
    {
        push_back(*(first + i));
    }
}

拷贝构造函数

        原理跟普通构造函数实现的机制一样,这里就不做过多说明,直接实现代码,如下:

vector(const vector<T>& v)
{
    int newsize = v.capacity();
    reserve(newsize);
    for (int i = 0; i < newsize; i++)
    {
        push_back(v._start[i]);
    }
}


三,析构函数

        析构函数在释放空间之后要记得将数据初始化,以保证安全性。

~vector()
{
    delete[] _start;
    _start = _finish = _endOfStorage = nullptr;
}


四,赋值运算符

        赋值运算符的实现跟拷贝构造函数实现机制相同。实现拷贝后要返回拷贝后的容器,以便实现连续赋值的情况。

vector<T>& operator= (vector<T> v)
{
    int newsize = v.capacity();
    reserve(newsize);
    for (int i = 0; i < newsize; i++)
    {
        push_back(v._start[i]);
    }
    return *this;
}


五,容器接口的实现

1,迭代器实现

        这里实现begin()、end()、cbegin()、cend()四种常用的迭代器。

//begin()和end()的实现

iterator begin()
{
    return _start;
}
iterator end()
{
    return _finish;
}

//cbegin()和cend()常量迭代器的实现
const_iterator cbegin() const
{
    const_iterator p = (const_iterator)_start;
    return p;
}
const_iterator cend() const
{
    const_iterator p = (const_iterator)_finish;
    return p;
}

2,“ [] ”运算符的实现

        “ [] ” 运算符实现分为两种,一种是变量的实现,一种是常量const的实现。

//变量实现

T& operator[](size_t pos)
{
    assert(pos >= 0 && pos < size());
    return _start[pos];
}

//常量实现
const T& operator[](size_t pos)const
{
    assert(pos >= 0 && pos < size());
    const T tem = (const T)_start[pos];
    return tem;
}

3,swap交换和resize重设大小

        swap接口实现机制是容器的全部数据实现交换。resize实现时要考虑参数大于容器大小和小于容器大小时的不同情况。

//交换算法

void swap(vector<T>& v)
{
    std::swap(_start, v._start);
    std::swap(_finish, v._finish);
    std::swap(_endOfStorage, v._endOfStorage);
}

//设定大小算法

void resize(size_t n, const T& value = T())
{
    assert(n >= 0);  //防止错误操作
    if (n < size())  //小于容器大小时的情况
    {
        _finish = _start + n;
    }
    else     //大于等于容器大小时的情况
    {
        reserve(n);
        for (int i = 0; i < n - size(); i++)
        {
            push_back(value);
        }
    }
}

4,insert插入和erase删除

        这里实现insert插入要注意的是选择位置时,因为不确定数据类型,因此要在指定迭代器的位置进行插入,最后返回该位置的迭代器。

        erase删除位置与insert插入位置一样,删除迭代器所指向的位置,最后返回该位置的迭代器。

//插入算法,在pos位置下插入数据x

iterator insert(iterator pos, const T& x)
{

    //要考虑指定插入的位置在合理范围之内
    assert(pos >= _start && pos < _finish);
    if (size() == capacity())
    {
        reserve(size() + 1);
    }
    for (iterator it = _finish - 1; it >= pos; it--)
    {
        *(it + 1) = *(it);
    }
    *pos = x;
    return pos;
}

//删除算法,删除pos位置下的数据
iterator erase(iterator pos)
{

    //要考虑指定删除的位置在合理范围之内
    assert(size() > 0);
    assert(pos >= _start && pos < _finish);
    for (iterator i = pos; i < _finish - 1; i++)
    {
        *(i) = *(i + 1);
    }
    _finish--;
    return pos;
}
文章来源地址https://www.toymoban.com/news/detail-787229.html

到了这里,关于【C++】vector容器的模拟实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C++】:STL源码剖析之vector类容器的底层模拟实现

    构造一个空vector size和capacity为0 将_start _finish _endofstorage 都置为空指针即可 传统写法 : 1). 新开辟一块和 v 同样容量的空间,更新 _start, _finish, _endofstorage 2). 将 v 中的数据拷贝到新开辟的空间中 注意 : 不要使用memcpy函数拷贝数据,如果数据是内置类型或浅拷贝的自定义类型

    2024年02月04日
    浏览(37)
  • 【C++】反向迭代器的模拟实现通用(可运用于vector,string,list等模拟容器)

    🌏博客主页: 主页 🔖系列专栏: C++ ❤️感谢大家点赞👍收藏⭐评论✍️ 😍期待与大家一起进步! 我们要写出一个通用的反向迭代器模拟而且在保证代码简介不繁琐的的情况下,一定程度上使用我们自己模拟的已经封装好的iterator迭代器可以简化许多步骤,首先我们要知

    2024年02月14日
    浏览(41)
  • 【C++】vector容器初步模拟

    送给大家一句话: 努力一点,漂亮—点,阳光一点。早晚有一天,你会惊艳了时光,既无人能替,又光芒万丈。 今天我我来进行vector的模拟实现,先简单的实现一下初步功能,使其对内置类型可以适配。(大部分与string很类似) vector是表示 可变大小数组 的序列容器。 就像

    2024年04月08日
    浏览(72)
  • 【C++STL】模拟实现vector容器

    本文带你进入vector的模拟实现,对于vector,是我们深入学习STL的必要途径。 根据库的实现方式,成员函数如下: c++11开始可以对成员变量使用缺省值,在这里我们可以使用缺省值。 size的大小为_finish - _start capacity的大小为_end_of_storage - _start 该函数的作用是:扩容。 思路:

    2024年02月16日
    浏览(27)
  • 【C++STL】“vector“容器的模拟实现

    🎉博客主页:小智_x0___0x_ 🎉欢迎关注:👍点赞🙌收藏✍️留言 🎉系列专栏:C++初阶 🎉代码仓库:小智的代码仓库 这里的 iterator 是 typedef T* iterator; 定义来的, T 是模板参数。 _start 是指向开始的指针变量。 _finish 是指向最后一个元素的下一位的指针变量。 _endofstorage 是

    2024年02月16日
    浏览(33)
  • STL之vector容器的介绍与模拟实现

    所属专栏:C“嘎嘎\\\" 系统学习❤️ 🚀 博主首页:初阳785❤️ 🚀 代码托管:chuyang785❤️ 🚀 感谢大家的支持,您的点赞和关注是对我最大的支持!!!❤️ 🚀 博主也会更加的努力,创作出更优质的博文!!❤️ vector的文档介绍 vector是表示可变大小数组的序列容器。 就像

    2024年01月21日
    浏览(31)
  • 【C++】vector模拟实现

    🚀 作者简介:一名在后端领域学习,并渴望能够学有所成的追梦人。 🚁 个人主页:不 良 🔥 系列专栏:🛸C++  🛹Linux 📕 学习格言:博观而约取,厚积而薄发 🌹 欢迎进来的小伙伴,如果小伙伴们在学习的过程中,发现有需要纠正的地方,烦请指正,希望能够与诸君一同

    2024年02月13日
    浏览(29)
  • C++ 模拟实现vector

    目录 一、定义 二、模拟实现 1、无参初始化 2、sizecapacity 3、reserve 4、push_back 5、迭代器 6、empty 7、pop_back 8、operator[ ] 9、resize 10、insert 迭代器失效问题 11、erase 12、带参初始化 13、迭代器初始化 14、析构函数 15、深拷贝 16、赋值运算符重载 完整版代码测试代码 本次参考SGI版

    2024年02月04日
    浏览(29)
  • C++模拟实现vector

    目录 1.代码实现 2.注意事项 1.成员变量 2. 不能使用memcpy函数拷贝数据 1.用string类型测试时,要考虑到vs可能把数据存储在数组buffer里面 3.insert函数中指针的失效性 1.加引用,那么就不能传常量,比如v.begin() + 3 2.加引用,就只能传变量了  4.erase成员函数的指针的失效性 这边以

    2024年02月17日
    浏览(33)
  • [C++]:11.模拟实现vector

    1.vector.h vector.h中其实包含了许多的头文件,我们在cpp中包含文件的时候头文件中还会去展开这四个头文件关于vector类主要在这个stl_vector.h中。 2.stl_vector.h 1.构造: ps:在当前的学习阶段看源码不要一行一行去看因为水平不足所以非常多基本上是看不懂的所以不要去一行一行去

    2024年01月16日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包