1.先定义一个类对象vector
为了防止和库里面发生冲突,定义一个命名空间,将类对象放在命名空间 里面
#include<iostream>
using namespace std;
namespace zjw {
class vector {
public:
private:
};
}
2.定义变量,需要一个迭代器,为了便于修改,变成任意类型的迭代器,我们使用函数模版,三个迭代器变量 _start用于指向顺序表的头,_finish指向顺序表的结尾的下一位,_end_of_storage保存总容量,在初始化列表中先设置为空
#include<iostream>
using namespace std;
namespace zjw {
template<class T>
class vector {
public:
typedef T * iterator;//迭代器类型
vector()
:_start(nullptr)
, _finish(nullptr)
, _end_of_storage(nullptr)
{
}
private:
iterator _start;
iterator _finish;
iterator _end_of_storage
};
}
3.定义函数
1.返回指向顺序表开始的迭代器函数
2.返回指向顺序表结尾的迭代器函数
3.返回容量大小的函数
4.返回顺序表元素多少
5.判断顺序表为空地的函数
5.一个运算符重载的函数(返回给定下标下的值)
#include<iostream>
using namespace std;
namespace zjw {
template<class T>
class vector {
public:
typedef T * iterator;//迭代器类型
vector()
:_start(nullptr)
, _finish(nullptr)
, _end_of_storage(nullptr)
{
}
iterator begin()//1
{
return _start;
}
iterator end()//2
{
return _finish;
}
size_t capacity()//3
{
return _end_of_storage - _start;
}
size_t size()//4
{
return _finish - _start;
}
bool empty()//5
{
return _finish == _start;
}
T& operator[](size_t pos)//6
{
assert(pos < size());
return _start[pos];
}
private:
iterator _start;
iterator _finish;
iterator _end_of_storage;
};
}
4.reserve函数开空间
void reserve(size_t n)
{
if (n > capacity)
{
T* tmp = new T[n];
if (_start)
{
memcpy(tmp, _start, sizeof(T) * size());
delete[] _start;
}
_start = tmp;
_finish = _start + size();
_end_of_storage = _start + n;
}
}
5.push_back函数尾插,以及尾删函数
void push_back(const T& x)
{
if (_finish == _end_of_storage)
{
reserve(capacity() == 0 ? 4 : capacity() * 2);
}
*_finish = x;
_finish++;
}
void pop_back()
{
assert(!empty());
--_finish;
}
6.测试尾插,尾删,下标遍历,迭代器遍历,范围for遍历,以及运算符重载返回对应下标的元素
void test1()
{
vector<int>v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
v1.push_back(5);
for (int i = 0; i < v1.size(); i++)
{
cout << v1[i] << " ";
}
cout << endl;
v1.pop_back();
v1.pop_back();
vector<int>::iterator it = v1.begin();
while (it != v1.end())
{
cout << *it << " ";
++it;
}
cout << endl;
v1.pop_back();
for (auto e : v1)
{
cout << e << " ";
}
cout << endl;
}
这里开空间的函数会发生问题
7.修改扩容函数
void reserve(size_t n)
{
if (n > capacity)
{ int sz=size();
T* tmp = new T[n];
if (_start)
{
memcpy(tmp, _start, sizeof(T) * size());
delete[] _start;
}
_start = tmp;
_finish = _start + sz;
_end_of_storage = _start + n;
}
}
8.resize函数
参数小于容量大小,相当于缩容,参数大于容量大小,相当于扩容,超过_finish的用值初始化
在讲resize之前看看模版会不会给匿名变量初始化,内置类型是否能初始化.
template <class T>
void f()
{
T x = T();
cout << x << endl;
}
void test3()
{
f<int>();
f<int*>();
f<double>();
}
发现可以,所以我们在resize里面当n>capacity(),我们可以把顺序表外的用来初始化,自定义类型相当于调用自己的构造函数,内置函数我们在这假装理解为调用自己的构造函数.
void resize(size_t n, T val = T())
{
if (n < size())
{
_finish = _start + n;
}
else
{
if (n > capacity())
reserve(n);
while (_finish != _start + n)
{
*_finish = val;
++_finish;
}
}
}
9.测试resize
void test2()
{
vector<int>v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
v1.push_back(5);
cout << v1.size() << endl;
cout << v1.capacity() << endl;
v1.resize(10);
cout << v1.size() << endl;
cout << v1.capacity() << endl;
for (auto e : v1)
{
cout << e << " ";
}
cout << endl;
v1.resize(3);
for (auto e : v1)
{
cout << e << " ";
}
}
}
10.封装一个打印函数用于任何vector对象
void func(const vector<int>& v)
{
for (int i = 0; i < v.size(); i++)//下标
{
cout << v[i] << " ";
}
cout << endl;
vector<int>::iterator it = v.begin();//迭代器
while (it != v.end())
{
cout << *it << " ";
++it;
}
cout << endl;
for (auto e : v)//范围for
{
cout << e << " ";
}
cout << endl;
}
因为打印不同对象的元素,为了区分是有一个this指针的,但是参数是const 无法产生this指针
解决方法,在这些函数后面加 const ,如果是const对象调用的话,就是权限平移,如果是非const的话,是权限缩小,都可以调用了,如果要限制别人去修改这个*it,我们可以定义一个const的迭代器
void func(const vector<int>& v)
{
for (int i = 0; i < v.size(); i++)//下标
{
cout << v[i] << " ";
}
cout << endl;
vector<int>::iterator it = v.begin();//迭代器
while (it != v.end())
{
cout << *it << " ";
++it;
}
cout << endl;
for (auto e : v)//范围for
{
cout << e << " ";
}
cout << endl;
}
void test4()
{
vector<int>v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
v1.push_back(5);
func(v1);
}
11.insert函数实现
void insert(iterator pos, const T& val)
{
assert(pos >= _start);
assert(pos <= _finish);
if (_finish == _end_of_storage)
{
reserve(capacity() == 0 ? 4 : capacity() * 2);
}
iterator end = _finish - 1;
while (end >= pos)
{
*(end + 1) = *end;
--end;
}
*pos = val;
++_finish;
}
测试insert
void test5()
{
vector<int>v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
v1.push_back(5);
for (auto e : v1)//范围for
{
cout << e << " ";
}
cout << endl;
auto pos = find(v1.begin(), v1.end(), 3);//找到3的位置
if (pos != v1.end())
{
v1.insert(pos, 30);//3前插入30
}
for (auto e : v1)//范围for
{
cout << e << " ";
}
cout << endl;
(*pos)++;//让3+1
for (auto e : v1)//范围for
{
cout << e << " ";
}
cout << endl;
}
}
pos保存的之前是3的地址,如果在3前插入一个30,pos所指向的位置就变成了30,*pos++,就变成了31;
如果我们不使用push_back(5)的话
void test5()
{
vector<int>v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
//v1.push_back(5);
for (auto e : v1)//范围for
{
cout << e << " ";
}
cout << endl;
auto pos = find(v1.begin(), v1.end(), 3);//找到3的位置
if (pos != v1.end())
{
v1.insert(pos, 30);//3前插入30
}
for (auto e : v1)//范围for
{
cout << e << " ";
}
cout << endl;
(*pos)++;//让3+1
for (auto e : v1)//范围for
{
cout << e << " ";
}
cout << endl;
}
}
会出现报错,到底是怎么一回事??
如何修改??
我们需要在未扩容前记录好pos距离_start的位置,拷到新空间,他与新_start也保持这个距离,更新pos
void insert(iterator pos, const T& val)
{
assert(pos >= _start);
assert(pos <= _finish);
if (_finish == _end_of_storage)
{
int len=pos - _start;
reserve(capacity() == 0 ? 4 : capacity() * 2);
pos = _start + len;
}
iterator end = _finish - 1;
while (end >= pos)
{
*(end + 1) = *end;
--end;
}
*pos = val;
++_finish;
}
这里的*pos里面的数据被清理,如果不清理应该是3++,应该是4,我们可以注释掉reserve中的delete看看
这里的问题被叫做迭代器失效
12.earse函数
void eraase(iterator pos)
{
assert(pos >= _start);
assert(pos < _finish);
iterator start = pos + 1;
while (start != _finish)
{
*(start - 1) = *start;
++start;
}
--_finish;
}
earse函数测试
void test6()
{
vector<int>v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
for (auto e : v1)//范围for
{
cout << e << " ";
}
cout << endl;
auto pos = find(v1.begin(), v1.end(), 2);
if (pos != v1.end())
{
v1.erase(pos);//删除2
}
(*pos)++;2位置上的元素++
for (auto e : v1)//范围for
{
cout << e << " ";
}
}
这里2删除后2的地址上存的就是3,然后给3++;在std中这个也算迭代器失效,由于这里是自己写的,所以没报错.
void test6()
{
std::vector<int>v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
for (auto e : v1)//范围for
{
cout << e << " ";
}
cout << endl;
auto pos = find(v1.begin(), v1.end(), 2);
if (pos != v1.end())
{
v1.erase(pos);
}
(*pos)++;
for (auto e : v1)//范围for
{
cout << e << " ";
}
}
}
上面会调用vector里面的函数
在不同编译器下有不同的处理情况。在vs中std我们认为迭代器失效,如果删除的是4的话,以我们实现的earse后,–_finish ;4那里的值没有被清理,所以后面的(*pos)++也不会出错,但在vs中我们使用vector里面的实现认为迭代器失效.
我们可以将代码拷过去在linux下试一下g++是怎么回事??
文章来源:https://www.toymoban.com/news/detail-830122.html
在g++中使用库中的vector函数删除数据4没有报错,对于迭代器失效,不同编译器也有不同处理.文章来源地址https://www.toymoban.com/news/detail-830122.html
13.整体代码
#include<iostream>
#include<assert.h>
#include<vector>
using namespace std;
namespace zjw {
template<class T>
class vector {
public:
typedef T * iterator;//迭代器类型
typedef T* const_iterator;//迭代器类型
vector()
:_start(nullptr)
, _finish(nullptr)
, _end_of_storage(nullptr)
{
}
iterator begin()const
{
return _start;
}
iterator end() const
{
return _finish;
}
size_t capacity()
{
return _end_of_storage - _start;
}
size_t size() const
{
return _finish - _start;
}
bool empty()
{
return _finish == _start;
}
T& operator[](size_t pos) const
{
assert(pos < size());
return _start[pos];
}
void reserve(size_t n)
{
int sz = size();
if (n > capacity())
{
T* tmp = new T[n];
if (_start)
{
memcpy(tmp, _start, sizeof(T) * size());
delete[] _start;
}
_start = tmp;
_finish = _start + sz;
_end_of_storage = _start + n;
}
}
void push_back(const T& x)
{
if (_finish == _end_of_storage)
{
reserve(capacity() == 0 ? 4 : capacity() * 2);
}
*_finish = x;
_finish++;
}
void pop_back()
{
assert(!empty());
--_finish;
}
void resize(size_t n, T val = T())
{
if (n < size())
{
_finish = _start + n;
}
else
{
if (n > capacity())
reserve(n);
while (_finish != _start + n)
{
*_finish = val;
++_finish;
}
}
}
void insert(iterator pos, const T& val)
{
assert(pos >= _start);
assert(pos <= _finish);
if (_finish == _end_of_storage)
{
int len=pos - _start;
reserve(capacity() == 0 ? 4 : capacity() * 2);
pos = _start + len;
}
iterator end = _finish - 1;
while (end >= pos)
{
*(end + 1) = *end;
--end;
}
*pos = val;
++_finish;
}
void erase(iterator pos)
{
assert(pos >= _start);
assert(pos < _finish);
iterator start = pos + 1;
while (start != _finish)
{
*(start - 1) = *start;
++start;
}
--_finish;
}
private:
iterator _start;
iterator _finish;
iterator _end_of_storage;
};
void test1()
{
vector<int>v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
v1.push_back(5);
for (int i = 0; i < v1.size(); i++)
{
cout << v1[i] << " ";
}
cout << endl;
v1.pop_back();
v1.pop_back();
vector<int>::const_iterator it = v1.begin();
while (it != v1.end())
{
cout << *it << " ";
++it;
}
cout << endl;
v1.pop_back();
for (auto e : v1)
{
cout << e << " ";
}
cout << endl;
}
void test2()
{
vector<int>v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
v1.push_back(5);
cout << v1.size() << endl;
cout << v1.capacity() << endl;
v1.resize(10);
cout << v1.size() << endl;
cout << v1.capacity() << endl;
for (auto e : v1)
{
cout << e << " ";
}
cout << endl;
v1.resize(3);
for (auto e : v1)
{
cout << e << " ";
}
}
void func(const vector<int>& v)
{
for (int i = 0; i < v.size(); i++)//下标
{
cout << v[i] << " ";
}
cout << endl;
vector<int>::iterator it = v.begin();//迭代器
while (it != v.end())
{
cout << *it << " ";
++it;
}
cout << endl;
for (auto e : v)//范围for
{
cout << e << " ";
}
cout << endl;
}
void test4()
{
vector<int>v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
v1.push_back(5);
func(v1);
}
void test5()
{
vector<int>v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
// v1.push_back(5);
for (auto e : v1)//范围for
{
cout << e << " ";
}
cout << endl;
auto pos = find(v1.begin(), v1.end(), 3);//找到3的位置
if (pos != v1.end())
{
v1.insert(pos, 30);//3前插入30
}
for (auto e : v1)//范围for
{
cout << e << " ";
}
cout << endl;
(*pos)++;//让3+1
cout << *pos << endl;
for (auto e : v1)//范围for
{
cout << e << " ";
}
cout << endl;
}
void test6()
{
std:: vector<int>v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
for (auto e : v1)//范围for
{
cout << e << " ";
}
cout << endl;
auto pos = find(v1.begin(), v1.end(), 4);
if (pos != v1.end())
{
v1.erase(pos);
}
(*pos)++;
for (auto e : v1)//范围for
{
cout << e << " ";
}
}
}
int main()
{
// zjw::test1();
zjw::test6();
// zjw::test3();
}
到了这里,关于【c++】vector的增删查改的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!