vector模拟实现

基础自实现结构

首先我们来看一看string的基础构造,有错误欢迎指正

template <class T>
class vector
{
public:
    //迭代器本质上就是数据的指针
    typedef T* iterator;
    typedef const T* const_iterator;  
     
    iterator begin();
    iterator end();
    const_iterator begin() const;
    const_iterator end() const;
    
     // construct and destroy
    vector();
    vector(const vector<T>& v);
    vector(int n,const T& value = T());
    //别的容器的拷贝迭代器
    template<class InputIterator>
    vector(InpurIterator first,InputIterator);
    //赋值
    vector<T>& operator=(vector<T> v);
    ~vector();

     // capacity
    size_t size() const;
    size_t capacity const;
    void reserve(size_t n);
    void resize(size_t n,const T& value = T())
    
    ///access///
    T& operator[](size_t n);
    const operator[](size_t n) const;

    ///modify/
    void push_back(const T& x);
    void pop_back;
    void swap(vector<T>& v)
    iterator insert(iterator pos,const T& x);
    iterator erase(iterator pos);

private:
    //这里给声明为空指针,初始化列表初始化,不然会报错
    iterator _start = nullptr;
    iterator _finish = nullptr;
    iterator _endofstorage = nullptr;     
};

1.迭代器iterator

由于vector和string不同,是用迭代器做底层实现,所以我们先写迭代器 

    typedef T* iterator;
    typedef const T* const_iterator;  
     
    iterator begin()
    {
        return _start;
    }

    iterator end()
    {
        return _finish;
    }

    const_iterator begin() const
    {
        return _start;
    }

    const_iterator end() const
    {
        return _finish;
    }

2.Construct and Destroy (构造和销毁)

2.1 构造,拷贝构造,析构 

//构造函数不需要我们实现,但是由于我们写了拷贝函数编译器就不会自己生成了
vector() = default;

vector(const vector<T>& v)
{
    reserve(v.capacity());
    
    for(auto e :v)
    {
        push_back(e);
    }
}

vector(int n,const T& value = T())
{
    reserve(n);
    
    while(n--)
        push_back(value);
}

~vector()
{
    //判空
    assert(_start != nullptr)

    delete[] _start;
    _start = _endofstorage = _finish = nullptr; 
}

2.2 =重载和inputiterator 

vector<T>& operator=(vector<T>& v)
{
    swap(v);
    
    return *this;
}

template<class InputIterator>
vector(InputIterator first,InputIterator end)
{
    while(first!=end)
    {
        push_back(*first);
        ++first;
    }
}

3.capacity(内存) 

3.1 size()和capacity()

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

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

3.2 reserve ☆ 

这个可以说贯穿全文,较为重要

void reserve(size_t n)
{
    if(n > capacity())
    {
        //创建一个old_size,防止size()造成的迭代器失效
        size_t old_size = size();
        T* tmp = new T[n];
        memcpy(tmp,_start,size()*sizeof(T));
        delete[] _start;

        _start = tmp;
        _finish = _start + old_size;
        _endofstorage = _start + n;
    }
}
    
        

3.3 resize

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

4.access(访问)[]符号重载

T& operator[](size_t n)
{
    assert(n < size());

    return *(_start + n);
}

const T& operator[](size_t n) const
{
    assert(n < size());

    return *(_start + n);
}

5. modify(修改) 

5.1 push_back(),pop_back(),swap()

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

void pop_back()
{
    assert(_finish != _start);

    --_finish;
}

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

5.2 insert

iterator insert(iterator pos, const T& x)
{
    assert(pos <= _finish);

    if(size() == capacity())
    {
        //start已经指向新空间,扩容要注意更新相应的pos
        size_t len = pos - _start;
        reserve(size() == 0 ? 4 : capacity() * 2);
        pos = _start + len;
    }

    iterator end = _finish;
    while(end != pos)    
    {
        *end = *(end - 1);   
        --end; 
    }
    
    *pos = x;
    ++_finish;

    return pos;
}

5.3 erase

iterator erase(iterator pos)
{
    assert(pos<size());
    assert(_start != nullptr)
    
    iterator it = pos + 1;
    while(it!=_finish)
    {
        *(it-1) = *it;
        ++it;
    }

    --_finish;
    return pos;
}

注意

个指针相减就是下标

不传参数才是默认构造

string的reserve会看情况缩容

而vector的reserve是坚决不缩容的

vector<string>用范围for要加引用:const auto& e:

operator[]主要是为了与C语言进行兼容。它可以像C语言数组一样操作。但at()是我们的首选,因为at()进行了边界检查,如果访问超过了vector的范围,将抛出一个例外。由于operator[]容易造成一些错误,所有我们很少用它,下面进行验证一下:

如果vector后跟的是string这种深拷贝类型,用memcpy就会导致浅拷贝报错

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值