C++之模拟实现vector(上)

简介: C++之模拟实现vector(上)

前言

因为学习了vector的相关知识,了解了vector大部分接口的底层实现原理,所以我决定自己模拟实现一个mini版的vector类,用来加深对vector各方面知识的理解。

如果有错误或不足之处,还望各位读者小伙伴们指出。


一、包含的相关头文件

#include<iostream>
#include<assert.h>
#include<vector>//要使用vector类,要记得包含这个头文件
using namespace std;

二、构造和析构

1.构造函数

1.无参

vector()
      :_start(nullptr)
      , _finish(nullptr)
      , _endOfStorage(nullptr)
    {}

2.n个T型元素进行初始化

1.普通

vector(size_t n, const T& value = T())
      :_start(nullptr)
      , _finish(nullptr)
      , _endOfStorage(nullptr)
    {
      reserve(n);
      //for (size_t i = 0; i < n; ++i)
      //{
      //  push_back(value);
      //}
      while (n--)
      {
        push_back(value);
      }
    }

2.特殊

因为,编译器会匹配最优匹配的函数进行调用。

为了避免将用n个Int型元素构造一个vector型的对象的函数调用匹配到下面的用T类型的迭代器初始化vector型的对象的构造函数(会发生错误的间接寻址),我们就得重载一个用n个Int数据初始化vector的构造函数

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

3.T型迭代器

template<class InputIterator>
    vector(InputIterator first, InputIterator last)
      :_start(nullptr)
      , _finish(nullptr)
      , _endOfStorage(nullptr)
    {
      while (first != last)
      {
        push_back(*first);
        first++;
      }
    }

2.拷贝构造

现代写法的优点在模拟实现string中已经介绍过,此处不再赘述。

//拷贝构造(现代写法)
    vector(const vector<T>& v)
      :_start(nullptr)
      , _finish(nullptr)
      , _endOfStorage(nullptr)
    {
      vector<T> temp(v.begin(), v.end());
      Swap(temp);
    }

自己实现的Swap可以避免深拷贝,提高效率

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

3.赋值运算符重载

//赋值运算符重载
    vector<T>& operator= (vector<T> v)
    {
      Swap(v);
      return *this;
    }

4.析构函数

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

三、iterator

Vector的迭代器是一个原生指针

typedef T* iterator;
    typedef const T* const_iterator;

1.普通对象

返回迭代器

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

2.const对象

返回const迭代器

const_iterator begin() const
    {
      return _start;
    }
    const_iterator end() const
    {
      return _finish;
    }

四、modify

1.push_back

尾插

void push_back(const T& x)
    {
      if (_finish == _endOfStorage)//插入前要判断空间是否满了
      {
        size_t newcapacity = (capacity() == 0) ? 4 : 2 * capacity();//要坚持是否第一次扩容
        reserve(newcapacity);
      }
      *_finish = x;
      _finish++;
    }

2.pop_back

尾删

void pop_back()
    {
      assert(!empty());//如果空间中没有元素就不能再尾删了
      _finish--;
    }

3.insert(含迭代器失效问题)

某个位置插入元素

这里有一个迭代器失效的问题,要小心处理

iterator insert(iterator pos, const T& x)
    {
      assert(pos >= _start);
      //assert(pos < _finish);
      assert(pos <= _finish);
      if (_finish == _endOfStorage)//如果插入操作进行了扩容,则原pos指针会失效(异地扩容会改变地址)
      {
        size_t len = pos - _start;
        size_t newcapacity = (capacity() == 0) ? 4 : 2 * capacity();
        reserve(newcapacity);
        //更新pos
        pos = _start + len;
      }
      iterator end = _finish;//挪动元素
      while (end > pos)
      {
        *end = *(end - 1);
        end--;
      }
      *pos = x;//插入元素
      _finish++;
      return pos;//pos是传值传参,因此函数内pos的更新不会使函数外的pos被更新(即,函数外的pos仍然失效)因此为了继续在函数外使用pos,我们把更新后的pos作为返回值传回去,更新函数外的pos
    }

具体如何处理下文的测试函数部分有介绍。

4.erase(含迭代器失效问题)

某位置删除一个元素

此处的迭代器意义发生改变,即迭代器失效

iterator erase(iterator pos)
    {
      assert(pos >= _start);
      assert(pos < _finish);
      //iterator begin = pos + 1;
      //while (begin < _finish)
      //{
      //  *(begin - 1) = *begin;
      //  begin++;
      //}
      iterator begin = pos;
      while (begin < _finish - 1)
      {
        *begin = *(begin + 1);
        begin++;
      }
      --_finish;
      return pos;
    }

具体如何处理下文的测试函数部分有介绍。

5.clear

void clear()
    {
      _finish = _start;
    }


相关文章
|
18天前
|
C++
c++的学习之路:13、vector(2)
c++的学习之路:13、vector(2)
26 0
|
5天前
|
C语言 C++ 容器
从C语言到C++_15(vector的模拟实现)+迭代器失效问题(下)
从C语言到C++_15(vector的模拟实现)+迭代器失效问题
17 0
|
5天前
|
算法 测试技术 C语言
从C语言到C++_15(vector的模拟实现)+迭代器失效问题(中)
从C语言到C++_15(vector的模拟实现)+迭代器失效问题
27 0
|
5天前
|
区块链 C语言 C++
从C语言到C++_15(vector的模拟实现)+迭代器失效问题(上)
从C语言到C++_15(vector的模拟实现)+迭代器失效问题
15 0
|
5天前
|
存储 算法 C语言
从C语言到C++_14(vector的常用函数+相关选择题和OJ题)(下)
从C语言到C++_14(vector的常用函数+相关选择题和OJ题)
13 0
|
5天前
|
算法 C语言 C++
从C语言到C++_14(vector的常用函数+相关选择题和OJ题)(中)
从C语言到C++_14(vector的常用函数+相关选择题和OJ题)
11 1
|
5天前
|
存储 C语言 C++
从C语言到C++_14(vector的常用函数+相关选择题和OJ题)(上)
从C语言到C++_14(vector的常用函数+相关选择题和OJ题)
13 0
|
9天前
|
C++ 容器
黑马c++ STL部分 笔记(3) vector容器
黑马c++ STL部分 笔记(3) vector容器
|
9天前
|
C++ 容器
黑马c++ STL部分 笔记(1) vector容器
黑马c++ STL部分 笔记(1) vector容器
|
12天前
|
C++ 容器
【C++】Vector -- 详解(下)
【C++】Vector -- 详解(下)