C++ STL - vector 模拟实现+解析迭代器

本文详细介绍了C++ STL中vector的使用,包括模拟实现、迭代器解析及失效问题。讨论了vector的扩容机制、元素访问、修改操作,特别是insert和erase如何导致迭代器失效,并提供了实例分析。此外,还探讨了vector>的理解,强调了迭代器失效的总结及其解决方案。
摘要由CSDN通过智能技术生成

目录

vector使用

vector模拟实现

vector实现解析:

memcpy进行元素拷贝问题:

扩容问题:

vector迭代器解析:

vector迭代器失效问题:

1.  示例一:一个典型的迭代器失效bug:insert实现

2. 示例二:insert引起的迭代器失效问题:

3. erase导致迭代器失效问题:

迭代器失效总结:

vector<vector<int>> 的理解:


vector使用

vector就是一个可变大小的数组,有多种构造函数。有析构函数,因为涉及内存管理,自然也有了拷贝构造和operator=。

大小相关:size获取数组大小,capacity获取当前可存储最大元素个数。主要是resize和reserve,resize改变数组大小,可变大可变小,扩size时可同时对元素初始化。reserve用于扩容,当知道vector大致存储元素个数时,可以用reserve缓解扩容带来的性能消耗。reserve的值小于当前capacity时,不会缩容。大于时会扩容,这里的容量不是size而是capacity。

我们知道,当vector的size==capacity时,再push_back会扩容,那么,vector的扩容机制是怎样的呢?实际上STL并没有规定vector的扩容机制,不同版本的STL有不同的存储策略。vs下capacity是按1.5倍增长的,g++是按2倍增长的。 这个问题经常会考察,不要固化的认为,vector增容都是2倍,具体增长多少是根据具体的需求定义的。vs是PJ版本STL,g++是SGI版本STL。

元素访问:支持operator[],这也是list,forward_list所不支持的。根本原因是底层存储为连续存储。back front at

修改:push_back pop_back,因为底层存储问题,push_front 和 pop_front时间复杂度较高,所以不支持头删头插,这也导致vector不适合做queue的适配容器。而可以做stack的适配容器。还比较重要的就是insert 和 erase了,也没什么,重载了多个版本,适于不同情况下的insert和erase,且都有返回值。insert返回新插入的第一个元素处的迭代器。erase返回删除元素或元素序列后的第一个元素处的迭代器。

说了很多FH,看https://cplusplus.com/reference/vector/vector/即可。

vector模拟实现

#ifndef STL_VECTOR_H
#define STL_VECTOR_H
#include "reverse_iterator.h"

namespace yzl
{
    // 拷贝构造,重载赋值都没实现。
    template<typename T, class Alloc = std::allocator<T>> // 就是一个用于申请T类型对象的类型而已。Alloc就是这么一个类型
    class vector {
    public:
        typedef T value_type;
        typedef value_type *iterator;
        typedef const value_type *const_iterator;

        typedef yzl::__reverse_iterator<iterator, T&, T*> reverse_iterator;
        typedef yzl::__reverse_iterator<const_iterator, const T&, const T*> const_reverse_iterator;
    private:
        iterator _start;
        iterator _finish;
        iterator _end_of_storage;
    public:
        iterator begin() {
            return _start;
        }

        iterator end() {
            return _finish;
        }

        const_iterator begin() const {
            return _start;
        }

        const_iterator end() const {
            return _finish;
        }

        const_iterator cbegin() const {
            return _start;
        }

        const_iterator cend() const {
            return _finish;
        }

        reverse_iterator rbegin()
        {
            return yzl::__reverse_iterator<iterator, T&, T*>(end());
        }

        reverse_iterator rend()
        {
            return yzl::__reverse_iterator<iterator, T&, T*>(begin());
        }

        yzl::__reverse_iterator<const_iterator, const T&, const T*> rbegin() const
        {
            return yzl::__reverse_iterator<const_iterator, const T&, const T*>(end());
        }

        const_reverse_iterator rend() const
        {
            return const_reverse_iterator(begin());
        }

        const_reverse_iterator crbegin() const
        {
            return const_reverse_iterator(end());
        }
        const_reverse_iterator crend() const
        {
            return const_reverse_iterator(begin());
        }
    public:
        vector()
                : _start(nullptr), _finish(nullptr), _end_of_storage(nullptr) {}

//        vector(size_t n, const T& val=T())
//        : _start(new T[n]), _finish(_start+n), _end_of_storage(_start+n)
//        {
//            for(size_t i = 0; i < n; ++i)
//                *(_start+i) = val;    // 调用T的赋值运算符
//        }
        // 必须有下面这个,如果是size_t  T的如上函数,则会出现报错。
        vector(int n, const T &value = T())
                : _start(new T[n]), _finish(_start + n), _end_of_storage(_finish) {
            for (int i = 0; i < n; ++i) {
                _start[i] = value;
            }
        }

        template<class InputIterator>
        vector(InputIterator first, InputIterator last)
                : _start(nullptr), _finish(nullptr), _end_of_storage(nullptr) {
//            size_t sz = last - first;
            while(first+sz != last)
            {
                ++sz;
            }
//            _start = new T[sz];
//  
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值