文章目录
1.vector类的介绍
首先vector是什么呢?vector就是顺序表
1. vector是表示可变大小数组的序列容器。
2. 就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素 进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自 动处理。
2.vector的基本用法
2.1 遍历vector
2.2 数据插入vector
还有insert()
2.3 vector容量
2.4 查找元素
vector里面没有find,因此我们使用find需要取algorithm里面去调用
需要包含头文件:
#include<algorithm>
2.5 vector包含vector(二维数组)
vector的二维数组与指针的二维数组的区别!
2.6 迭代器失效
2.6 迭代器覆盖
3.vector的底层(模拟实现)
3.1 begin and end
iterator begin()
{
return _start;
}
iterator end()
{
return _finish;
}
const_iterator cbegin() const
{
return _start;
}
const_iterator cend() const
{
return _finish;
}
3.2 拷贝
// v2(v1)
vector1(const vector1<T>& v)
{
reserve(v.capacity());
for (auto& e : v)
{
push_back(e);
}
}
3.3 赋值
//v1=v3
vector1<T>& operator= (vector1<T> v)
{
swap(v);
return *this;
}
3.4 size and capacity
size_t size() const
{
return _finish - _start;
}
size_t capacity() const
{
return _endOfStorage - _start;
}
3.5 operator[]
T& operator[](size_t pos)
{
assert(pos < size());
return _start[pos];
}
const T& operator[](size_t pos)const
{
assert(pos < size());
return _start[pos];
}
3.6 完整代码
myvector.h:
#pragma once
#include <iostream>
#include <cassert>
namespace myvector
{
template<class T>
class vector1
{
public:
// Vector的迭代器是一个原生指针
typedef T* iterator;
typedef const T* const_iterator;
iterator begin()
{
return _start;
}
iterator end()
{
return _finish;
}
const_iterator cbegin() const
{
return _start;
}
const_iterator cend() const
{
return _finish;
}
// construct and destroy
vector1() : _start(nullptr), _finish(nullptr), _endOfStorage(nullptr) {}
vector1(int n, const T& value = T())
{
reserve(n);
for (size_t i = 0; i < n; i++)
{
push_back(value);
}
}
template<class InputIterator>
vector1(InputIterator first, InputIterator last)
{
while (first != last)
{
push_back(*first);
++first;
}
}
// v2(v1)
vector1(const vector1<T>& v)
{
reserve(v.capacity());
for (auto& e : v)
{
push_back(e);
}
}
//v1=v3
vector1<T>& operator= (vector1<T> v)
{
swap(v);
return *this;
}
~vector1()
{
delete[] _start;
_start = _finish = _endOfStorage = nullptr;
}
// capacity
size_t size() const
{
return _finish - _start;
}
size_t capacity() const
{
return _endOfStorage - _start;
}
void reserve(size_t n);
void resize(size_t n, const T& value = T());
///access///
T& operator[](size_t pos)
{
assert(pos < size());
return _start[pos];
}
const T& operator[](size_t pos)const
{
assert(pos < size());
return _start[pos];
}
///modify/
void push_back(const T& x);
void pop_back();
bool empty()
{
return _start == _finish;
}
void swap(vector1<T>& v);
void insert(iterator pos, const T& x);
void erase(iterator pos);
private:
iterator _start; // 指向数据块的开始
iterator _finish; // 指向有效数据的尾
iterator _endOfStorage; // 指向存储容量的尾
};
template<class T>
void print_vector1(const vector1<T>& v)
{
for (size_t i = 0; i < v.size(); i++)
{
std::cout << v[i] << " ";
}
std::cout << std::endl;
}
template<class T>
void vector1<T>::reserve(size_t n)
{
if (n > capacity())
{
T* tmp = new T[n];
size_t old_size = size();
for (size_t i = 0; i < old_size; i++)
{
tmp[i] = _start[i];
}
delete[] _start;
_start = tmp;
_finish = tmp + old_size;
_endOfStorage = tmp + n;
}
}
template<class T>
void vector1<T>::resize(size_t n, const T& value)
{
if (n > size())
{
reserve(n);
while (_finish < _start + n)
{
*_finish = value;
++_finish;
}
}
else
{
_finish = _start + n;
}
}
template<class T>
void vector1<T>::push_back(const T& value)
{
if (_finish == _endOfStorage)
reserve(capacity() == 0 ? 4 : capacity() * 2);
*_finish = value;
++_finish;
}
template<class T>
void vector1<T>::pop_back()
{
assert(!empty());
--_finish;
}
template<class T>
void vector1<T>::swap(vector1<T>& v)
{
// 交换指针
std::swap(_start, v._start);
std::swap(_finish, v._finish);
std::swap(_endOfStorage, v._endOfStorage);
}
template<class T>
void vector1<T>::insert(iterator pos, const T& x)
{
assert(pos >= _start);
assert(pos <= _finish);
if (_finish == _endOfStorage)
{
size_t len = pos - _start;
reserve(capacity() == 0 ? 4 : capacity() * 2);
// 如果扩容了要更新pos
pos = _start + len;
}
iterator it = _finish - 1;
while (it >= pos)
{
*(it + 1) = *it;
--it;
}
*pos = x;
++_finish;
}
template<class T>
void vector1<T>::erase(iterator pos)
{
assert(pos >= _start);
assert(pos < _finish);
iterator it = pos + 1;
while (it < _finish)
{
*(it - 1) = *it;
++it;
}
--_finish;
}
void test_vector1()
{
vector1<int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
v1.push_back(4);
v1.push_back(4);
print_vector1(v1);
vector1<double> v2;
v2.push_back(1.1);
v2.push_back(2.2);
v2.push_back(3.1);
print_vector1(v2);
v2.insert(v2.begin(), 11.11);
print_vector1(v2);
v2.insert(v2.begin(), 11.11);
print_vector1(v2);
v2.insert(v2.begin(), 11.11);
print_vector1(v2);
v2.insert(v2.begin(), 11.11);
print_vector1(v2);
v2.insert(v2.begin(), 11.11);
print_vector1(v2);
v2.erase(v2.begin());
print_vector1(v2);
v2.erase(v2.begin() + 4);
print_vector1(v2);
}
}
main.cpp:
#include"myvector.h"
using namespace std;
using namespace myvector;
int main()
{
test_vector1();
return 0;
}
3.7 补充说明
为什么这里不像以前一样写三个文件:
myvector.h、myvector.cpp、main.cpp呢?
这是因为如果写三个文件的话会造成重定义的错误,如下:
一开始非常懊恼!
然后我也是查阅了一些相关资料,他们是这样说的:
所以以后在遇到模板类的时候,我们要把声明和定义都放在.h文件中!!!