C++ stl库中vector的简单实现

vector图示详解:

 

 

图来自《stl源码分析》 

namespace yhy

{

    template<class T>

    class vector

    {

    public:



        typedef T* iterator;//定义了一个简单的迭代器,迭代器在stl中起到指针的作用,但是有时候纯指针的迭代器在一些数据结构中如list中无法起到所有作用,所以有时候是指针,有时候是自定义类型。

        typedef const T* const_iterator; //const 迭代器保证在遍历vector时不会意外地修改元素的值

        iterator begin()
        {
            return _start;
        }

        iterator end()
        {
            return _finish;

        }

        const_iterator cbegin()const

        {
            return _start;
        }//cbegin()函数返回一个const_iterator类型的迭代器,指向vector的第一个元素

        const_iterator cend()const//同上
        {
            return _finish;
        }//




        vector()//无参构造

            :_start(nullptr), _finish(nullptr), _endOfStorage(nullptr){}
       
        vector(int n, const T& value = T())
        {
            _start = new T[n];
            _finish = _endOfStorage = _start + n;
            for (int i = 0; i < n; i++)
            {
                push_back(value);
            }
        }

        ~vector()
        {
            delete[] _start;
            _start = _finish = _endOfStorage = nullptr;
        }
            template<class InputIterator>

           

            vector(InputIterator first, InputIterator last)
                :_start(nullptr), _finish(nullptr), _endOfStorage(nullptr)//注意在初始化列表的时候,对象就已经被实例化了,因此可以进行后面代码的操作
            {
                _start = first; _finish = _endOfStorage = last;
                iterator i = first;
                while (i < last)
                {
                    push_back(*i);
                    i++;
                }
            }
                vector(const vector<T>& v)
            {
                    vector<T> tmp(v._start, v.cend);//在这里我们要先实例化一个tmp是由于进行深拷贝,不实例化会浅拷贝,如果浅拷贝,导致一个空间被重复释放造成程序崩溃
                    swap(tmp);

            }

                vector<T>& operator= (vector<T> v)//与上面同理,为何要将两个对象进行交换?而不直接赋值?因为直接赋值会使得两个对象中的_start,_finish指针指向同一个空间,也就是只进行了浅拷贝
                {
                    swap(v);
                    return *this;
                }

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

                size_t capacity() const
                {
                    return _endOfStorage - _start;
                }

                    void reserve(size_t n)
                      {
                        if (n > capacity())//如果n大于目前容量,则扩容,然后将原数据迁移到现空间内
                        {
                            size_t size = _finish - _start;
                            T* tmp = new T[n];
                            for (size_t i = 0; i < size; i++)
                            {
                                tmp[i] = _start[i];//想象一下如果vector里成员也是一个vector对象会怎么样?必须要进行深拷贝1,而这里的=符号将会使用我们重载的那个=
                            }
                            _start = tmp;
                            _finish = _start + size;
                            
                        }
                        _endOfStorage = _start + n;
                       
                      }

                    void resize(size_t n, const T& value = T())
                    {
                       
                        if (size() < n )
                        {
                            if (n > capacity())
                            {
                                resize(n);
                            }
                            while (_finish < _start + n)
                            {
                                *_finish = value;
                                _finish++;
                            }
                        }
                        else
                        {
                            _finish = _start + n;
                        }
                       
                       
                    }



               

                    T& operator[](size_t pos)
                {
                        return *(_start + pos);
                }

                const T& operator[](size_t pos) const
                {
                    return *(_start + pos);
                }



               

                   void push_back(const T& x)
                {
                    if (_finish ==_endOfStorage)
                    {
                         size_t newcapacity = capacity() == 0 ? 4 : 2 * capacity();
                         reserve(newcapacity);
                    }
                    *_finish = x;
                    _finish++;
                }

                    void pop_back()
                    {
                        assert(size() > 0);
                        _finish--;
                    }

                    void swap(vector<T>& v)
                    {
                        iterator tmp = nullptr;
                        tmp = _start;
                    }

                    iterator insert(iterator pos, const T& x)//由于该成员函数由于扩容问题,可能会导致迭代器失效因此不能直接用传参的pos,而应该用它计算pos到——start的距离,再传入一个新pos
                    {
                        assert(pos >= _start);
                        assert(pos < _finish);
                        size_t len = pos - _start;
                        if (_finish == _endOfStorage)
                        {
                            size_t newcapacity = capacity() == 0 ? 1 : 2 * capacity();
                            reserve(newcapacity);
                        }
                        iterator newpos = _start + len;
                        iterator i = _finish;
                        for (i; i > newpos; i--)
                        {
                            *i = *i + 1;
                        }
                        *newpos = x;
                        ++_finish;
                    }
                   iterator erase(iterator pos)//由于erase会发生迭代器失效,由于erase在删除数据时会发生移动,因此如果刚好删除的是最后一个元素时,一但后面的数据移动,判断就会失效,那么将会无限循环,因此如果想使用这种函数,那么一定要接收erase的返回值再进入循环进行判断
                    {
                       return nullptr;
                    }
                   void swap(vector<T>& v)
                   {
                       std::swap(_start, v._start);
                       std::swap(_finish, v._finish);
                       std::swap(_endOfStorage v._start);
                   }
    private:

        iterator _start; // 指向数据的开始

        iterator _finish; // 指向有效数据的尾

        iterator _endOfStorage; // 指向存储容量的尾

    };

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值