可以把vector看作升级版的数组,可采用下标进行访问,非常高效,大小可动态改变,会自动扩容,数据存储在堆空间上。
VECROR
成员变量、函数及模板总览
cpp
namespace ahunb{
template<class T>
class vector
{
public:
// Vector的迭代器是一个指针 //
typedef T* iterator;
typedef const T* const_iterator;
/ Iterators /
iterator begin();
iterator end();
const_iterator cbegin();
const_iterator cend() const;
// construct and destroy
vector();
vector(int n, const T& value = T());
template<class InputIterator>
vector(InputIterator first, InputIterator last);
vector(const vector<T>& v);
vector<T>& operator= (vector<T> v);
~vector();
/ capacity /
size_t size() const ;
size_t capacity() const;
void reserve(size_t n);
void resize(size_t n, const T& value = T());
///Element access//
T& operator[](size_t pos);
const T& operator[](size_t pos)const;
///modifiers/
void push_back(const T& x);
void pop_back();
void swap(vector<T>& v);
iterator insert(iterator pos, const T& x);
iterator erase(Iterator pos);
private:
iterator _start; // 指向数据块的开始
iterator _finish; // 指向有效数据的尾
iterator _endOfStorage; // 指向存储容量的尾
};
构造函数和析构函数
无参构造函数
cpp
vector()
{}
构造n个元素大小的空间并初始化
cpp
vector(int n, const T& value = T())
{
resize(n);
for (int i = 0; i < n; i++)
{
vector[i] = value;
}
}
通过某个对象的两个迭代器来构造
cpp
template<class InputIterator>
vector(InputIterator first, InputIterator last)
{
while (first != last)
{
push_back(*first);
first++;
}
}
拷贝构造函数
cpp
vector(const vector<T>& v)
{
reserve(v.capacity());
for (auto e : v)
{
push_back(e);
}
}
赋值运算符重载
cpp
vector<T>& operator= (vector<T> v)
{
swap(v);
return *this;
}
析构函数
cpp
~vector()
{
delete[] _start;
_start = _finish = _endofstorage = nullptr;
}
迭代器
返回第一个元素迭代器
多提供一个加const的 ,以防有const对象要调用
cpp
iterator begin()
{
return _start;
}
const_iterator begin() const
{
return _start;
}
返回最后一个元素迭代器
cpp
iterator end()
{
return _finish;
}
const_iterator end() const
{
return _finish;
}
容量和大小相关函数
返回当前大小
cpp
size_t size()
{
return _finish - _start;
}
const size_t size() const
{
return _finish - _start;
}
返回当前容量上限
cpp
size_t capacity()
{
return _endofstorage - _start;
}
const size_t capacity() const
{
return _endofstorage - _start;
}
reserve函数
改变vector的capacity(容量)变量
当n>capacity将capacity改为n,否则不变
对新空间进行拷贝时要深拷贝,否则delete时会出现野指针
cpp
void reserve(size_t n)
{
if (n > capacity())
{
int sz = size();
iterator tmp = new T[n];
if (_start)
{
for (int i = 0; i < sz; i++)
{
tmp[i] = _start[i];//注意使用深拷贝
}
delete[] _start;
}
_start = tmp;
_finish = _start + sz;
_endofstorage = _start+n;
}
}
resize函数
改变vector的size(当前大小)变量
当n>size时,将大小改为n,并将新增加的大小初始化
否则直接将大小改为n就可以
cpp
void resize(size_t n, const T& value = T())
{
if (n > size())
{
reserve(n);
while (_finish < _start + n)
{
*_finish = value;
_finish++;
}
}
else
{
_finish = _start + n;
}
}
访问元素接口
[ ]运算符重载
cpp
T& operator[](size_t pos)
{
assert(pos < size());
return _start[pos];
}
const T& operator[](size_t pos)const
{
assert(pos < size());
return _start[pos];
}
添加元素与删除元素
尾插
cpp
void push_back(const T& x)
{
if (_finish == _endofstorage)
{
int cp = capacity();
cp = (cp == 0 ? 4 : cp * 2);
reserve(cp);
}
*_finish = x;
++_finish;
}
指定位置插入元素
- 注意扩容之后会存在pos失效问题,因为扩容之后原对象改变了_start等指针,指向了新的区间,但pos指向的还是原来的区间,所以在第七行和第九行对pos进行了更新。
cpp
iterator insert(iterator pos, const T& x)
{
assert(pos <= finish);
assert(pos >= _start);
if (_finish == _endofstorage)
{
int n = pos - _start;
reserve(capacity() + 1);
pos = _start + n;
}
iterator end = _finish;
while (end > pos)
{
*end = *(end - 1);
end--;
}
*pos = x;
_finish++;
return pos;
}
删除指定位置元素
cpp
iterator erase(iterator pos)
{
assert(pos < finish);
assert(pos >= _start);
if (_finish - 1 != pos)
{
iterator begin = pos;
while (begin < _finish - 1)
{
*begin = *(begin + 1);
}
}
_finish--;
return pos+1;
}
尾删
cpp
void pop_back()
{
erase(_finish - 1);
}
交换
cpp
void swap(vector<T>& v)
{
std::swap(_start, v._start);
std::swap(_finish, v._finish);
std::swap(_endofstorage, v._endofstorage);
}
源代码
cpp
//vector.h
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <assert.h>
using namespace std;
namespace ahu
{
template <class T>
class vector
{
public:
typedef T* iterator;
typedef const T* const_iterator;
vector()
{}
vector(int n, const T& value = T())
{
resize(n);
for (int i = 0; i < n; i++)
{
vector[i] = value;
}
}
template<class InputIterator>
vector(InputIterator first, InputIterator last)
{
while (first != last)
{
push_back(*first);
first++;
}
}
vector(const vector<T>& v)
{
reserve(v.capacity());
for (auto e : v)
{
push_back(e);
}
}
vector<T>& operator= (vector<T> v)
{
swap(v);
return *this;
}
~vector()
{
delete[] _start;
_start = _finish = _endofstorage = nullptr;
}
//Iterator
iterator begin()
{
return _start;
}
iterator end()
{
return _finish;
}
const_iterator begin() const
{
return _start;
}
const_iterator end() const
{
return _finish;
}
//Capacity
size_t size()
{
return _finish - _start;
}
const size_t size() const
{
return _finish - _start;
}
size_t capacity()
{
return _endofstorage - _start;
}
const size_t capacity() const
{
return _endofstorage - _start;
}
void reserve(size_t n)
{
if (n > capacity())
{
int sz = size();
iterator tmp = new T[n];
if (_start)
{
for (int i = 0; i < sz; i++)
{
tmp[i] = _start[i];
}
delete[] _start;
}
_start = tmp;
_finish = _start + sz;
_endofstorage = _start+n;
}
}
void resize(size_t n, const T& value = T())
{
if (n > size())
{
reserve(n);
while (_finish < _start + n)
{
*_finish = value;
_finish++;
}
_finish = _start + n;
}
else
{
_finish = _start + n;
}
}
//Element 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];
}
//Modifiers
void push_back(const T& x)
{
if (_finish == _endofstorage)
{
int cp = capacity();
cp = (cp == 0 ? 4 : cp * 2);
reserve(cp);
}
*_finish = x;
++_finish;
}
void pop_back()
{
erase(_finish - 1);
}
void swap(vector<T>& v)
{
std::swap(_start, v._start);
std::swap(_finish, v._finish);
std::swap(_endofstorage, v._endofstorage);
}
iterator insert(iterator pos, const T& x)
{
assert(pos <= finish);
assert(pos >= _start);
if (_finish == _endofstorage)
{
int n = pos - _start;
reserve(capacity() + 1);
pos = _start + n;
}
iterator end = _finish;
while (end > pos)
{
*end = *(end - 1);
end--;
}
*pos = x;
_finish++;
return pos;
}
iterator erase(iterator pos)
{
assert(pos < finish);
assert(pos >= _start);
if (_finish - 1 != pos)
{
iterator begin = pos;
while (begin < _finish - 1)
{
*begin = *(begin + 1);
}
}
_finish--;
return pos+1;
}
private:
iterator _start = nullptr; // 指向数据块的开始
iterator _finish = nullptr; // 指向有效数据的尾
iterator _endofstorage = nullptr; // 指向存储容量的尾
};
}
//vector.cpp
#define _CRT_SECURE_NO_WARNINGS
#include "vector.h"
//#include <vector>
using namespace ahu;
int main()
{
vector<int> v1;
v1.push_back(1);
v1.push_back(1);
v1.push_back(1);
v1.push_back(1);
v1.push_back(1);
v1.push_back(1);
v1.push_back(1);
v1.push_back(1);
//v1.push_back(1);
vector<int> v2(v1);
for (size_t i = 0; i < v2.size(); i++)
{
cout << v2[i] << endl;
}
cout << "-------------------------------------" << endl;
//v2.reserve(100);
//cout << v2.capacity() << endl;
//cout << v2.size()<<endl;
//v2.resize(50);
//cout << v2.capacity() << endl;
//cout << v2.size() << endl;
//v2.reserve(25);
//cout << v2.capacity() << endl;
//cout << v2.size() << endl;
v2.insert(v2.begin()+3, 100);
for (size_t i = 0; i < v2.size(); i++)
{
cout << v2[i] << endl;
}
cout << "-------------------------------------" << endl;
v2.erase(v2.begin() + 9);
v2.erase(v2.begin() + 8);
v2.erase(v2.begin() + 7);
v2.erase(v2.begin() + 6);
v2.erase(v2.begin() + 5);
v2.erase(v2.begin() + 4);
v2.erase(v2.begin()+3);
for (size_t i = 0; i < v2.size(); i++)
{
cout << v2[i] << endl;
}
}
✨本文收录于C++语法及练习
当你喜欢一篇文章时,点赞、收藏和关注是最好的支持方式。如果你喜欢我的文章,请不要吝啬你的支持,点赞👍、收藏⭐和关注都是对我最好的鼓励。感谢你们的支持!如有问题欢迎指正!