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

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

五、capacity

1.size

容器的元素个数

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

2.capacity

容器的容量

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

3.empty

判空函数

bool empty()
    {
      return _start == _finish;
    }

4.resize

改变元素个数

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

5.reserve

改变容量

void reserve(size_t n)
    {
      if (n > capacity())
      {
        size_t oldsize = size();
        T* temp = new T[n];
        if (_start)
        {
          //memcpy(temp, _start, sizeof(T)* len);
          //这里不能使用memcpy,因为它进行的是浅拷贝,会导致原空间与新空间的内容指向同一空间,当原空间被销毁时,析构函数会将它所指的空间也销毁,导致新空间指向为野指针,导致程序崩溃
          for (size_t i = 0; i < oldsize; ++i)//只能一个元素一个元素的赋值(赋值运算符重载进行深拷贝)
          {
            temp[i] = _start[i];
          }
          delete[] _start;
        }
        _start = temp;
        _finish = _start + oldsize;
        _endOfStorage = _start + n;
      }
    }

六、access

1.普通对象的接口(可读可写)

T& operator[](size_t pos)
    {
      assert(pos < size());
      return _start[pos];
    }

2.const对象的接口(只读)

const T& operator[](size_t pos)const
    {
      assert(pos < size());
      return _start[pos];
    }

七、私有属性

private:
    iterator _start; // 指向数据块的开始
    iterator _finish; // 指向有效数据的尾
    iterator _endOfStorage; // 指向存储容量的尾

八、测试

主函数:

//test.cpp
#include"vector.h"
int main()
{
  //Jinger::Test1();
  //Jinger::Test2();
  //Jinger::Test3();
  //Jinger::Test4();
  Jinger::Test5();
  return 0;

测试:

void Test1()
  {
    vector<int> v;
    v.resize(10, -1);
    for (auto e : v)
    {
      cout << e << " ";
    }
    cout << endl;
  }

运行结果:

void Test2()
  {
    vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    v.push_back(4);
    v.push_back(4);
    v.push_back(4);
    vector<int>::iterator it = find(v.begin(), v.end(), 3);
    if (it != v.end())
    {
      it = v.insert(it, 30);
    }
    // insert以后 it还能否继续使用 -- 不能,可能发生扩容导致迭代器失效(野指针)
    //如果要继续使用it就需要对it进行更新,insert函数的返回值就是更新后的it值。
    (*it)++;
    *it *= 100;
    for (auto e : v)
    {
      cout << e << " ";
    }
    cout << endl;
  }

void Test3()
  {
    vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    v.push_back(4);
    // it失效还是不失效? ——失效,因为it位置的内容被删除,所有it的含义被改变了(此时,it会指向被删除元素的下一个元素)
    vector<int>::iterator it = find(v.begin(), v.end(), 4);
    if (it != v.end())
    {
      v.erase(it);
    }
    // 读 
    cout << *it << endl;
    // 写
    (*it)++;
    cout << *it << endl;
    for (auto e : v)
    {
      cout << e << " ";
    }
    cout << endl;
  }

//erase操作会导致it迭代器失效。再次使用时要进行更新它(erase函数的返回值就是更新后的it迭代器,此时它指向刚刚被删除元素的下一个元素)
  //虽然部分编译器(linux的g++下不报错)中erase后的迭代器还能继续使用,但不能保证所有编译器下它都不报错,因此我们同意认为erase后的迭代器会失效,如果再次使用它必须要更新它
  void Test4()
  {
    // 要求删除所有偶数
    vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(2);
    v.push_back(3);
    v.push_back(4);
    v.push_back(4);
    v.push_back(4);
    vector<int>::iterator it = v.begin();
    while (it != v.end())
    {
      if (*it % 2 == 0)
      {
        it = v.erase(it);
      }
      else
      {
        it++;
      }
    }
    for (auto e : v)
    {
      cout << e << " ";
    }
    cout << endl;
  }

void Test5()
  {
    vector<vector<int>> vv;
    vector<int> v(5, 1);
    vv.push_back(v);
    vv.push_back(v);
    vv.push_back(v);
    vv.push_back(v);
    vv.push_back(v);
    for (size_t i = 0; i < vv.size(); ++i)
    {
      for (size_t j = 0; j < vv[i].size(); ++j)
      {
        cout << vv[i][j] << " ";
      }
      cout << endl;
    }
    cout << endl;
  }


总结

以上就是今天要讲的内容,本文介绍了作者自己实现的vector类的相关类成员函数,如果文章中的内容有错误或者不严谨的部分,欢迎大家在评论区指出,也欢迎大家在评论区提问、交流。

最后,如果本篇文章对你有所启发的话,希望可以多多支持作者,谢谢大家!

相关文章
|
1天前
|
存储 算法 C++
【C++】详解STL容器之一的 vector
【C++】详解STL容器之一的 vector
|
6天前
|
C++ 容器
【c++】优先级队列|反向迭代器(vector|list)
【c++】优先级队列|反向迭代器(vector|list)
5 0
|
6天前
|
C++ 容器
C++之评委打分案例(vector与deque容器练习)
C++之评委打分案例(vector与deque容器练习)
9 1
|
6天前
|
算法 C++ 容器
C++之vector容器操作(构造、赋值、扩容、插入、删除、交换、预留空间、遍历)
C++之vector容器操作(构造、赋值、扩容、插入、删除、交换、预留空间、遍历)
15 0
|
7天前
|
存储 算法 编译器
【C++航海王:追寻罗杰的编程之路】vector
【C++航海王:追寻罗杰的编程之路】vector
9 0
|
8天前
|
算法 编译器 Linux
【C++/STL】:vector容器的底层剖析&&迭代器失效&&隐藏的浅拷贝
【C++/STL】:vector容器的底层剖析&&迭代器失效&&隐藏的浅拷贝
9 0
|
8天前
|
存储 算法 C++
【C++/STL】:vector容器的基本使用
【C++/STL】:vector容器的基本使用
15 1
|
9天前
|
存储 安全 算法
C++的内置数组和STL array、STL vector
C++的内置数组和STL array、STL vector
|
11天前
|
存储 算法 C++
C++一分钟之-容器概览:vector, list, deque
【6月更文挑战第21天】STL中的`vector`是动态数组,适合随机访问,但插入删除非末尾元素较慢;`list`是双向链表,插入删除快但随机访问效率低;`deque`结合两者优点,支持快速双端操作。选择容器要考虑操作频率、内存占用和性能需求。注意预分配容量以减少`vector`的内存重分配,使用迭代器而非索引操作`list`,并利用`deque`的两端优势。理解容器内部机制和应用场景是优化C++程序的关键。
22 5
|
18天前
|
编译器 C++ 容器
【C++进阶】深入STL之vector:深入研究迭代器失效及拷贝问题
【C++进阶】深入STL之vector:深入研究迭代器失效及拷贝问题
23 0