【C++】-- STL之vector模拟实现(二)

简介: 【C++】-- STL之vector模拟实现

3.赋值运算符重载

(1)传统的赋值运算符重载

1.         vector<T> operator=(vector<T> v)
2.    {
3.      if (this != &v)
4.      {
5.        //1.清理空间,让空间变干净
6.        delete[] _start;
7. 
8.        //2.申请空间
9.        _start = new T[v.capacity()];
10. 
11.         //3.拷贝数据
12.           for (size_t i = 0; i < v.size(); i++)
13.           {
14.             _start[i] = v._start[i];
15.           }
16. 
17.         //4.更新大小及容量
18.         _finish = _start + v.size();
19.         _end_of_storage = _start + v.capacity();
20.       }
21.     }

(2)现代的赋值运算符重载函数

1. void swap(vector<T> v)
2.    {
3.      ::swap(_start, v._start);
4.      ::swap(_finish, v._finish);
5.      ::swap(_end_of_storage, v._end_of_storage);
6.    }        
7. 
8.         vector<T> operator=(vector<T> v)
9.    {
10.       swap(v);//直接交换*this和v的内容
11.       return *this;
12.     }

4.析构函数

1.         ~vector()
2.    {
3.      if (_start)
4.      {
5.        delete[] _start;//释放空间
6.      }
7.      _start = _finish = _end_of_storage = nullptr;//置空
8.    }

5.迭代器

(1)普通迭代器

1. iterator begin()
2.    {
3.      return _start;
4.    }
5. 
6.    iterator end()
7.    {
8.      return _finish;
9.    }

(2)const迭代器

1.    const_iterator begin() const
2.    {
3.      return _start;
4.    }
5. 
6.    const_iterator end() const
7.    {
8.      return _finish;
9.    }

6.operator[ ]

1. //普通operator[]   
2.         T& operator[](size_t i)
3.    {
4.      assert(i < size());//断言i是否合法
5.      return _start[i];
6.    }
7. 
8. //const operator[]
9. const T& operator[](size_t i) const
10.     {
11.       assert(i < size());
12.       return _start[i];
13.     }

7.size( )

1.    size_t size() const
2.    {
3.      return _finish - _start;//结束位置-起始位置
4.    }

8.capacity( )

1.    size_t capacity() const
2.    {
3.      return _end_of_storage - _start;//可用空间-起始位置
4.    }

9.empty( )

1. bool empty()
2.    {
3.      return _start == _finish;//起始空间是否为结束空间
4.    }

10.reserve( )

开空间,扩展_capacity,_size不变

(1)保存对象大小

(2)申请新空间

(3)拷贝字符串

(4)释放旧空间

(6)更新新空间的大小及容量

1. void reserve(size_t n)
2.    {
3.      size_t sz = size();//1.保存对象的大小
4.      if (n > capacity())
5.      {
6.        T* tmp = new T[n];//2.申请新空间
7.        if (_start)
8.        {
9.          //3.拷贝数据,memcpy是浅拷贝,会把旧空间地址又拷贝过去,不能用memcpy
10. for (size_t i = 0; i < v.size(); i++)
11.               {
12.                 _start[i] = v._start[i];
13.               }
14.           delete[] _start;//4.释放旧空间
15.         }
16. 
17.         _start = tmp;//5.指向新空间
18. 
19.         //6.更新新空间的大小及容量
20.         _finish = _start + sz;
21.         _end_of_storage = _start + capacity();
22.       }
23.     }

11.resize( )

(1)当resize的大小比原来小,说明空间够,只需要修改大小即可

(2)当resize的大小比原来大,说明空间不够,同时也说明容量可能不够,要判断是否需要申请容量

1.    void resize(size_t n, T val = T())
2.    {
3.      //1.当resize的大小比原来小,说明空间够,只需要修改大小即可
4.      if (n < size())
5.      {
6.        _finish = _start + n;
7.      }
8.      //2.当resize的大小比原来大,空间不够
9.      else
10.       {
11.         //是否需要扩容
12.         if (n > capacity)
13.         {
14.           reserve(n);
15.         }
16. 
17.         //赋值
18.         while (_finish < _start + n)
19.         {
20.           *_finish = val;
21.           _finish++;
22.         }
23.       }
24.     }

12.push_back( )

尾插时,需要:

(1)判断增容

(2)赋值

(3)更新大小

1. void push_back(const T& x)
2.    {
3.      //1.判断是否需要增容
4.      if (_finish == _end_of_storage)
5.      {
6.        size_t newCapacity = capacity() == 0 ? 4 : capacity() * 2;
7.        reserve(newCapacity);
8.      }
9. 
10.       //2.赋值
11.       *_finish = x;
12. 
13.       //3.更新大小
14.       ++_finish;
15.     }

13.pop_back( )

尾删:

(1)判空

(2)直接更新大小

1. void pop_back()
2.    {
3.      assert(!empty());
4.      _finish--;
5.    }

14.insert( )

在固定位置插入元素,需要考虑迭代器失效的问题

(1)判断是否需要扩容+保存并更新迭代器(增容时就要先保存pos的位置,扩容后要更新迭代器)

(2) 挪数据

(3)插入数据

(4)更新pos位置

1.    void insert(iterator& pos, const T& x)
2.    {
3.      //1.判断容量是否够用,增容+更新迭代器
4.      if (_finish == _end_of_storage)
5.      {
6.        size_t len = pos - _start;
7.        size_t newCapapcity = capacity()==0 ?  4 : capacity() * 2;
8. 
9.        //更新pos,解决增容后pos失效的问题
10.         pos = _start + len;
11.       }
12. 
13.       //2.pos位及之后的数据往后挪
14.       iterator end = _finish - 1;
15.       while (end >= pos)
16.       {
17.         *(end + 1) = *end;
18.         end--;
19.       }
20. 
21.       //3.插入数据
22.       *pos = x;
23.       _finish++;
24. 
25.       //4.由于pos位置的元素向后挪动了一位,pos也要向后挪动一位指向原来指向的元素的位置
26.       pos = pos + 1;
27.     }

15.erase( )

(1)将pos位置及之后的元素向后挪

(2)更新大小

1.    iterator erase(iterator pos)
2.    {
3.      assert(pos);
4. //1.将pos位置及之后的元素向后挪
5.      iterator it = pos + 1;
6.      while (it < _finish)
7.      {
8.        *(it - 1) = *it;
9.        it++;
10.       }
11. 
12. //2.更新大小
13.       _finish--;
14. 
15.       return pos;
16.     }
相关文章
|
3天前
|
存储 自然语言处理 安全
C++ STL标准库 《string原理与实战分析》
C++ STL标准库 《string原理与实战分析》
13 0
|
1天前
|
存储 算法 程序员
【C++进阶】深入STL之 栈与队列:数据结构探索之旅
【C++进阶】深入STL之 栈与队列:数据结构探索之旅
|
1天前
|
存储 缓存 编译器
【C++进阶】深入STL之list:模拟实现深入理解List与迭代器
【C++进阶】深入STL之list:模拟实现深入理解List与迭代器
|
1天前
|
C++ 容器
【C++进阶】深入STL之list:高效双向链表的使用技巧
【C++进阶】深入STL之list:高效双向链表的使用技巧
|
1天前
|
编译器 C++ 容器
【C++进阶】深入STL之vector:深入研究迭代器失效及拷贝问题
【C++进阶】深入STL之vector:深入研究迭代器失效及拷贝问题
|
1天前
|
存储 算法 程序员
【C++进阶】深入STL之vector:构建高效C++程序的基石
【C++进阶】深入STL之vector:构建高效C++程序的基石
|
1天前
|
编译器 C++
【C++进阶】深入STL之string:模拟实现走进C++字符串的世界
【C++进阶】深入STL之string:模拟实现走进C++字符串的世界
|
1天前
|
安全 算法 C语言
【C++进阶】深入STL之string:掌握高效字符串处理的关键
【C++进阶】深入STL之string:掌握高效字符串处理的关键
【C++进阶】深入STL之string:掌握高效字符串处理的关键
|
2天前
|
C++ 容器 存储
【C++语言】想学STL,先细细拿捏string类,万字详解string类 (内附精美思维导图)
【C++语言】想学STL,先细细拿捏string类,万字详解string类 (内附精美思维导图)
|
2天前
|
大数据 C++ 索引
C++ STL标准库 《vector向量原理与实战分析》
C++ STL标准库 《vector向量原理与实战分析》
9 0