c++ vector emulates the implementation code

  • 2020-07-21 09:37:23
  • OfStack

The introduction of vector

1. vector is a sequence container representing a variable-size array.
2. Like array 1, vector USES continuous storage to store elements. This means that vector elements can be accessed using subscripts, as efficient as array 1. But unlike an array, its size can be changed dynamically, and its size is automatically handled by the container.
3. Essentially, vector USES dynamically allocated arrays to store its elements. When a new element is inserted, the array needs to be resized to increase storage. This is done by allocating a new array and then moving all the elements to that array. This is a relatively expensive task in terms of time because vector does not redistribute the size every time a new element is added to the container.
4. vector allocation strategy: vector allocates some extra space to accommodate possible growth because the storage space is larger than the actual storage space required. Different libraries use different strategies to balance the use and reallocation of space. But in any case, the reallocation should be logarithmically incremented so that the insertion of one element at the end is done at constant time complexity.
5. Therefore, vector takes up more storage space in order to gain the ability to manage storage space and grow dynamically in an efficient way.
6. Compared with other dynamic sequence containers (deques, lists and forward_lists), vector is more efficient in accessing elements and relatively efficient in adding and removing elements at the end. Other deletes and inserts that are not at the end are less efficient. Better iterators and references than lists and forward_lists series 1.

vector is a very important container in C++ STL. Understanding the underlying implementation principle of vector can help us to use vector more skillfully.

c++ vector simulation implementation code:


#include<iostream>
using namespace std;
namespace bit
{
 template<typename T>
 class vector
 {
 public:
 typedef T* iterator;
 public:
 T operator[](int i)
 {
  return start[i];
 }
 public:
 vector() :start(nullptr), finish(nullptr), end_of_sorage(nullptr)
 {
 }
 vector(size_t n, const T& value = T()) :start(nullptr), finish(nullptr), end_of_sorage(nullptr)
 {
  reserve(n);// To increase 
  while (n--!=0) // To populate the 
  {
  push_back(value);
  }
 }
 template<class InPutIterator> // Created by front and rear Pointers 
 vector(InPutIterator first, InPutIterator last):start(nullptr), finish(nullptr), end_of_sorage(nullptr)
 {
  reserve(last-first);// Apply for space first 
  while (first != last)
  {
  push_back(*first);
  first++;
  }
 }
 ~vector()
 {
  delete[]start;
  start = finish = end_of_sorage = nullptr;
 }
 public:
 int size()
 {
  return finish - start;
 }
 int capacity()
 {
  return end_of_sorage - start;
 }
 bool empty()
 {
  return finish == start;
 }
 void swap(vector<T>& v)
 {
  std::swap(start, v.start);
  std::swap(finish, v.finish);
  std::swap(end_of_sorage, v.end_of_sorage);
 }
 void reserve(size_t new_capacity) //  capacity 
 {
  if (new_capacity > capacity())
  {
  int old_size = size(); // Original size  
  T* newV = new T[new_capacity]; // New Application space 
  if (start)// When the original content is not empty 
  {
   for (int i = 0; i < size(); i++) // Copy it into the new space 
   {
   newV[i] = start[i];
   }
  }
  delete[]start;// Delete existing space 
  start = newV;// Point to the new space 
  finish = start + old_size;
  end_of_sorage = start + new_capacity;
  }
 }
 void resize(int new_size, const T& value = 0) // Expansion of the size 
 {
  if (new_size <= size())
  {
  finish = start + new_size;
  }
  if (new_size > capacity())
  {
  reserve(new_size * 2);
  }
  iterator p = finish;
  finish = start + new_size;// Point to the new size 
  while (p != finish) // fill value
  {
  *p = value;
  p++;
  }
 }
 public:
 void push_back(const T &c)
 {
  insert(end(), c);
 }
 public:
 typedef T* iterator;
 iterator begin()
 {
  return start;
 }
 iterator end()
 {
  return finish;
 }
 public:
 iterator insert(iterator pos, const T &x) // in pos Pre-position insertion x
 {
  if (size() + 1 >= capacity())
  {
  size_t oldpos = pos - start;
  size_t new_capacity = capacity() ? (capacity() * 2) : 1;
  reserve(new_capacity);
  pos = start + oldpos;
  }
  T* p = finish;
  for (; p != pos; p--)
  {
  *p = *(p - 1);
  }
  *p = x;
  finish++;
  return pos;
 }
 iterator erase(iterator pos) // delete pos Location value 
 {
  T* p = pos;
  while (p != finish - 1)
  {
  *p = *(p + 1);
  p++;
  }
  finish--;
  return pos;
 }
 private:
 T* start;// Point to the beginning 
 T* finish;// Pointing to the last 1 Of the elements 1 A position 
 T* end_of_sorage;// It goes to the bottom of the maximum volume 1 A position 
 };
}
int main()
{
 int ar[] = { 1,2,3,4,5,6,7,7 };
 bit::vector<int>v1(ar, ar + 6);
 bit::vector<int>v2;
 bit::vector<int>v3(10,'a');
 v1.erase(v1.end()-1);
 v1.insert(v1.begin(), 0);
 v1.swap(v3);
 for (int i = 0; i < v1.size(); i++)
 {
 cout << v1[i] << " ";
 }
 return 0;
}

conclusion


Related articles: