文章目录
可以简单的将vector想象成一个可扩容的线性表

vector创建二维数组
1,直接创建;
//M行N列的二维数组
vector<vector<int>>arr(M,vector<int>(N));
2,利用扩容函数;
vector<vector<int>>arr;
arr.resize(M);
for(int i=0;i<M;i++)
{
arr[i].resize(N);
}
vector的初始化
int main()
{
int ar[] = { 12,23,34 };
vector<int>ar1;
vector<int>ar2 = {12,23,34,45,56};
vector<int>ar3(10, 23);
vector<int>ar4({ 12,23,34,45,56 });
vector<int>ar5(ar1);
vector<int>ar6(std::move(ar2));
ar1 = { 12,23,34,45 };
//ar1 = ar;erro
ar1 = std::move(ar3);
return 0;
}
int main()
{
vector<Object> objvec = { Object(10),Object(20),Object(30),Object(40) };
cout << objvec.size() << endl;
cout << objvec.capacity() << endl;
return 0;
}
先构建4个对象,然后在vector里面拷贝构造
通过迭代器对vector里面的数据进行访问
#include<vector>
class Object
{
private:
int value;
public:
Object(int x = 0) :value(x) { cout << "Object" << endl; }
Object(const Object& obj) :value(obj.value) { cout << "Object &" << endl; }
Object(Object&& obj) :value(obj.value) { cout << "move Object&&" << endl; }
Object& operator=(const Object& obj)
{
value = obj.value;
cout << "operator=" << endl;
return *this;
}
Object& operator=(const Object&& obj)
{
value = obj.value;
cout << "operator=" << endl;
return *this;
}
~Object()
{
cout << "~Object" << endl;
}
int& Value()
{
return value;
}
};
int main()
{
vector<Object> objvec = { Object(10),Object(20),Object(30),Object(40) };
cout << objvec.size() << endl;
cout << objvec.capacity() << endl;
for (int i = 0; i < objvec.size(); ++i)
{
cout << objvec[i].Value() << endl;
}
for (int i = 0; i < objvec.capacity(); ++i)
{
cout << objvec.at(i).Value() << endl;
}
vector<Object>::iterator it = objvec.begin();
for (; it != objvec.end(); ++it)
{//迭代器里面已经对->和*进行了运算符的重载
cout << it->Value() << " " << (*it).Value() << endl;
}
it = objvec.begin();
for (; it != objvec.end(); ++it)
{
cout << it->Value() << " " << endl;
it->Value() += 100;
cout << (*it).Value() << " "<< endl;
}
//如果不想让迭代器改变值用常性迭代器
vector<Object>::const_iterator cit = objvec.begin();
//const int *p;p++;
for (; cit != objvec.end(); ++cit)
{
//cout << cit->Value()<< endl;erro长迭代器不能调用普通的方法
//两种解决办法1,将迭代器改为非常性;
//2,在类里面在设计一个常性方法
}
return 0;
}
int main()
{
vector<Object>objvec = { Object(10),Object(20),Object(30),Object(40) };
for (auto x : objvec)//推演出x是Object类型而不是iterator
{
cout << x.Value() << endl;
}
return 0;
}
int main()
{
vector<Object>objvec = { Object(10),Object(20),Object(30),Object(40) };
//for (auto x : objvec)//推演出x是Object类型而不是iterator
//{
// cout << x.Value() << endl;
//}
//不希望更改value就加const
//没有好坏之分只有程序员的需求
for (const auto &x : objvec)//推演出x是Object类型而不是iterator
{
cout << x.Value() << endl;
}
return 0;
}
//不建议这样写
int main()
{
vector<Object>objvec = { Object(10),Object(20),Object(30),Object(40) };
Object* op = objvec.data();
cout << op->Value() << endl;
op->Value() += 10;
op->~Object();
delete[]op;
}
reserve
#include<vector>
class Object
{
private:
int value;
public:
Object(int x = 0) :value(x) { cout << "Object" << endl; }
Object(const Object& obj) :value(obj.value) { cout << "Object &" << endl; }
Object(Object&& obj) :value(obj.value) { cout << "move Object&&" << endl; }
Object& operator=(const Object& obj)
{
value = obj.value;
cout << "operator=" << endl;
return *this;
}
Object& operator=(const Object&& obj)
{
value = obj.value;
cout << "operator=" << endl;
return *this;
}
~Object()
{
cout << "~Object" << endl;
}
int& Value()
{
return value;
}
};
int main()
{
vector<Object>objvec = { Object(10),Object(20),Object(30),Object(40) };
cout << objvec.size() << endl;
cout << objvec.capacity() << endl;
objvec.reserve(10);
cout << objvec.size() << endl;
cout << objvec.capacity() << endl;
}
扩容导致迭代器失效
int main()
{
vector<Object>objvec = { Object(10),Object(20),Object(30),Object(40) };
cout << objvec.size() << endl;
cout << objvec.capacity() << endl;
vector<Object>::iterator it = objvec.begin();
Object& obj = objvec.back();
objvec.reserve(10);
cout << objvec.size() << endl;
cout << objvec.capacity() << endl;
}
resize
int main()
{
vector<Object>objvec = { Object(10),Object(20),Object(30),Object(40) };
cout << objvec.size() << endl;
cout << objvec.capacity() << endl;
/*vector<Object>::iterator it = objvec.begin();
Object& obj = objvec.back();
objvec.reserve(10);*/
objvec.resize(10);
cout << objvec.size() << endl;
cout << objvec.capacity() << endl;
}
int main()
{
vector<Object>objvec = { Object(10),Object(20),Object(30),Object(40) };
cout << objvec.size() << endl;
cout << objvec.capacity() << endl;
/*vector<Object>::iterator it = objvec.begin();
Object& obj = objvec.back();
objvec.reserve(10);*/
objvec.resize(10);
cout << objvec.size() << endl;
cout << objvec.capacity() << endl;
objvec.resize(2);
cout << objvec.size() << endl;
cout << objvec.capacity() << endl;
}
int main()
{
vector<Object>objvec = { Object(10),Object(20),Object(30),Object(40) };
cout << objvec.size() << endl;
cout << objvec.capacity() << endl;
initializer_list<Object>arr = { Object(10),Object(20) };
//c11
int a{ 10 };
int* p{ nullptr };
int ar[]{ 12,23,34 };
vector<int>veci{ 12,23,34 };
list<int>ilist{ 12,23,34,45 };
/*vector<Object>::iterator it = objvec.begin();
Object& obj = objvec.back();
objvec.reserve(10);*/
objvec.resize(10);
cout << objvec.size() << endl;
cout << objvec.capacity() << endl;
}
列表方式初始化
#include<initializer_list>
template<class T>
class SeqList
{
T* data;
int maxsize;
int cursize;
public:
SeqList(int sz = 10) :data(T new[sz], maxsize(sz), cursize(sz)) {}
SeqList(std::initializer_list<T>init)
{
maxsize = init.size();
cursize = maxsize;
data = (T*)malloc(sizeof(T) * maxsize);
}
};
int main()
{
SeqList<int>seqlist{ 12,23,34,45 };
return 0;
}
assign
注意这几种扩容均可能导致迭代器失效
int main()
{
vector<Object>objvec = { Object(10),Object(20),Object(30),Object(40) };
cout << objvec.size() << endl;
cout << objvec.capacity() << endl;
//objvec.reserve(10);//容量的扩张,不能收缩
//objvec.resize(10);//size()=>不仅能扩容,还能增加对象的数量
//objvec.resize(2);//size()=>不能收缩空间,但是能减少对象的个数
for (auto& x : objvec)
{
cout << x.Value() << endl;
}
objvec.assign(10, Object(100));
cout << objvec.size() << endl;
cout << objvec.capacity() << endl;
for (auto& x : objvec)
{
cout << x.Value() << endl;
}
}
reserve(1000)空间太大可用空间过多如何处理
int main()
{
vector<Object>objvec = { Object(10),Object(20),Object(30),Object(40) };
cout << objvec.size() << endl;
cout << objvec.capacity() << endl;
objvec.reserve(100000);
cout << objvec.size() << endl;
cout << objvec.capacity() << endl;
{//tmp的生存期只在{}里面
vector<Object>tmp(objvec);
tmp.swap(objvec);
//交换只交换first.last,end
}
cout << objvec.size() << endl;
cout << objvec.capacity() << endl;
}
插入函数
push_back
push_back(100);是隐士构造,先创建无名对象object在对其拷贝构造,注意这里只有在单参构造函数里面才可以,如果你想拒绝隐士构建在但参构造函数前加explicit
int main()
{
vector<Object>objvec = { Object(10),Object(20),Object(30),Object(40) };
cout << objvec.size() << endl;
cout << objvec.capacity() << endl;
vector<Object>::iterator it = objvec.begin();
cout << it->Value() << endl;
objvec.push_back(Object(100));
cout << it->Value() << endl;
}
插入函数可能会导致迭代器失效
insert函数
int main()
{
vector<Object>objvec = { Object(10),Object(20),Object(30),Object(40) };
cout << objvec.size() << endl;
cout << objvec.capacity() << endl;
vector<Object>::iterator it = objvec.begin();
objvec.insert(it,Object(20));//在头部插入(类似顺序表)效率很低
//objvec.insert(it,{Object(100),Object(200)});
return 0;
}
emplace_back()原位构建
int main()
{
vector<Object>objvec;
objvec.reserve(10);
objvec = { Object(10),Object(20),Object(30),Object(40) };
cout << objvec.size() << endl;
cout << objvec.capacity() << endl;
//objvec.push_back(Object(10));这样先构建无名对象,在给vector里面移动构造,在析构无名对象而原位构建直接构建
//objvec.push_back(10);隐士构建
objvec.emplace_back(100);
}
template<class T,class ...Arg>
void Make(T* p, Arg... arg)
{
new(p) T(arg...);
}
int main()
{
Object* p = (Object*)malloc(sizeof(Object));
Object obj(12);
Make(p, 12);
Make(p, 12, 23);
Make(p, std::move(obj));
}
迭代器的失效问题
a:当容器调用erase方法后,当前位置到容器末尾元素的所有的迭代器全部失效了
b:当容器调用insert方法后,当前位置到容器末尾元素的所有的迭代器全部失效了
c:对于insert插入来说,如果引起容器内存扩容,那么原来容器的所有的迭代器就全部失效了
d:不同容器的迭代器是不能进行比较运算的
迭代器失效了以后,问题该怎么解决?
对插入/删除点的迭代器进行更新操作
我们发现:erase和insert都会返回一个新的迭代器。给当前位置插入元素或者删除元素,当前元素的后边元素都会发生移动,指向当前元素的迭代器就失效了。
当我们增加或者删除操作,会把操作完的当前位置的新的迭代器返回。
(生成当前位置的合法的迭代器并返回)
我们用it去接收返回的更新的迭代器。
我们删除了元素以后,后边的元素都会前移,所以it就不要++了
我们现在来解决插入元素的问题
插入一个元素,就把原当前位置的元素都后移了。
所以我们的it还要再多执行1次++了。