二.模拟实现vector
0.看一看源码SGI
1.vector.h
vector.h中其实包含了许多的头文件,我们在cpp中包含文件的时候头文件中还会去展开这四个头文件关于vector类主要在这个stl_vector.h中。
2.stl_vector.h
1.构造:
ps:在当前的学习阶段看源码不要一行一行去看因为水平不足所以非常多基本上是看不懂的所以不要去一行一行去看要全方面的去看有一些看不懂问题不大。
2.析构函数:
3.push_back()
1.构造函数:
1-1:参数为空的!
1.构造函数的初始化列表给全空:
2.构造函数的内容给赋值全空:
3.C++11 支持的声明变量的时候初始化(走的初始化列表):
4.综上所述第三个方法最方便:我们都可以在定义的时候去初始化非常的方便。
vector(size_t n , const T& val=T())
:start(nullptr)
,finish(nullptr)
,end_of_storage(nullptr)
{
}
vector()
{
start = nullptr;
finish = nullptr;
end_of_storage = nullptr;
}
private:
iterator start = nullptr;
iterator finish = nullptr;
iterator end_of_storage = nullptr;
1-2:n个数据的!
情况一:n个数据传第二个参数初始化数据的:
情况二:n个数据不传第二个参数就开空间不初始化的:
1.对于我情况二的操作其实本质是初始化容量空间为全 val (内置类型的默认构造值),但是我的finish == start所以在后面使用的时候数据进入是赋值进入:
vector(size_t n , const T& val=T())
{
resize(n,val);
}
vector(int n , const T& val=T())
{
resize(n,val);
}
1-3:范围构造:
//1-3:范围初始化:
//1-4:使用新的模板方便使用不同类型的迭代器进行范围构造
template<class InputIterator>
vector(InputIterator left, InputIterator right)
{
while (left != right)
{
push_back(*left);
left++;
}
}
2.析构函数:
//析构:
~vector()
{
delete[] start;
start = nullptr;
finish = nullptr;
end_of_storage = nullptr;
}
3.迭代器+遍历数据:
3-1:迭代器:
//3.迭代器:
iterator begin()const
{
return start;
}
iterator end()const
{
return finish;
}
iterator_const cbegin()const
{
return start;
}
iterator_const cend()const
{
return finish;
}
iterator rbegin()const
{
return finis - 1;
}
iterator rend()const
{
return start-1;
}
iterator_const crbegin()const
{
return finis - 1;
}
iterator_const crend()const
{
return start - 1;
}
3-2:数据遍历:
void print_value()const
{
assert(start != end_of_storage);
int num = finish - start;
for (int i = 0; i < num; i++)
{
cout << *(start + i) << " ";
}
cout << endl;
}
T& operator[](size_t pos)
{
return *(start + pos);
}
void text_2()
{
sfpy::vector<int> v1(10, 2);
sfpy::vector<int> v2(v1);
sfpy::vector<int> v3(10);
sfpy::vector<int>::iterator it_1 = v1.begin();
while (it_1 != v1.end())
{
cout << *it_1 << " ";
it_1++;
}
cout << endl;
v1.print_value();
for (int i = 0; i < v1.size(); i++)
{
cout << v1[i] << " ";
}
cout << endl;
sfpy::vector<int>::iterator it_2 = v2.begin();
while (it_2 != v2.end())
{
cout << *it_2 << " ";
it_2++;
}
cout << endl;
v2.print_value();
for (int i = 0; i < v2.size(); i++)
{
cout << v2[i] << " ";
}
cout << endl;
}
4.空间问题:
4-1:size() 和capacity
//4.size() 和 capacity()
size_t size()const
{
return finish - start;
}
size_t capacity()const
{
return end_of_storage - start;
}
4-2:resize 和 reserve:
void reserve(size_t n)
{
//assert(n > capacity());
//1.重新配置空间:
T* tmp = new T[n];
if (n > capacity())
{
size_t n_1 = size();
for (size_t i = 0; i < n; i++)
{
if (i < n_1)
{
tmp[i] = *(start + i);
}
else
{
tmp[i] = T();
}
}
delete[] start;
start = tmp;
finish = tmp + n_1;
end_of_storage = tmp + n;
}
}
void resize(size_t n, T val = T())
{
if (n > size())
{
reserve(n);
while (finish < start + n)
{
*finish = val;
++finish;
}
}
else
{
finish = start + n;
}
}
1.关于reserve的补充:
2.为什么不去使用memcpy这样的的函数本质这是一个浅拷贝。
3.调用delete[] 释放空间+调用析构函数。
4.内置类型使用memcpy没有问题。
5.对于自定义类型来说使用memcpy会产生浅拷贝的问题
4-3:empty
bool empty()
{
if (size() == 0)
{
return true;
}
else
{
return false;
}
}
4-4:shrink_to_fit
void shrink_to_fit()
{
assert(size() >= capacity);
//1.重新配置空间:
size_t n = size();
T* tmp = new T[n];
//减少:
memcpy(tmp, start, size(T) * n);
start = tmp;
finish = end_of_storage = tmp + n;
}
5.增删查改:
5-1:push_back()
void push_back(const T& val)
{
if (finish == end_of_storage)
{
size_t new_capacity =(start == finish ? 4 : (capacity() * 2));
reserve(new_capacity);
}
(*finish) = val;
finish++;
}
5-2:pop_back()
void pop_back()
{
assert(size() != 0);
//resize(size() - 1);
(*finish) = T();
finish--;
}
5-3:find()
1.find()是一个全局函数不是一个特定的类就有一个find() .
2.find()是通过类模板实现的。
3.find()的返回值是一个iterator。
template <class T>
T* find(T* first, T* last, const T& val)
{
while (first != last)
{
if (*first == val)
return first;
++first;
}
return last;
}
5-4:insert() :在find之前插入
iterator insert(iterator position, const T& val)
{
size_t pos = position - start;
size_t n = size();
if (finish == end_of_storage)
{
size_t new_capacity = (start == finish ? 4 : (capacity() * 2));
reserve(new_capacity);
}
//void * memmove ( void * destination, const void * source, size_t num );
memcpy(start + pos + 1, start + pos, (n - (pos))*sizeof(T));
*(start + pos) = val;
finish++;
return start + pos;
}
5-5:erase() : 删除find位置
iterator erase(iterator position)
{
assert(size() != 0);
size_t pos = position - start;
size_t n = size();
//void * memmove ( void * destination, const void * source, size_t num );
memcpy(start + pos , start + pos +1, (n - (pos+1)) * sizeof(T));
finish--;
return start + pos;
}
文章来源:https://www.toymoban.com/news/detail-794333.html
5-6:insert和erase
1.在vs下insert和erase传进去的迭代器在使用之后就不可以继续使用了(有可能发生迭代器失效的情况)。
2.在vs下是会认为迭代器失效。
3.模拟实现insert和erase —> insert返回插入新的元素的迭代器,erase返回删除元素的下一个元素的迭代器。
4.pos就不要继续使用应该去使用insert和erase的返回值。文章来源地址https://www.toymoban.com/news/detail-794333.html
到了这里,关于[C++]:11.模拟实现vector的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!