int main()
{
vector<int> ar1;
vector<int> ar2 = { 12,23,34 };
vector<int> ar3({ 12,23,34 });//初始化列表
vector<int> ar4(10, 23);//初始化十个空间,将23拷贝进去
vector<int> ar5 = ar2;
vector<int> ar6(std::move(ar3));
}
int main()
{
vector<Object> vec = { Object(10),Object(20),Object(30),Object(40)};
cout << vec.size() << endl;
cout << vec.capacity() << endl;
}
1.for循环,下标访问
2.at()访问
3.迭代器访问,相当于面向对象的指针
4.常性迭代器,无法改变值,只可取值
5.基于范围的for循环,使用引用的方式,因为如果是变量,每一步都会拷贝一个对象。
for (int i = 0; i < vec.size(); i++)
{
cout << vec[i].Value() << endl;
//obj.Value()
}
//for (int i = 0; i < vec.capacity(); i++)
//{ //代表的是容量,后面访问的均为空
// cout << vec.at(i).Value() << endl;
// //vec.obj.value()
//}
vector<Object>::iterator it = vec.begin();
for (; it != vec.end(); it++)
{
cout << it->Value() << " " << endl;
// it->Value() += 10;
// cout << (*it).Value() << " " << endl;
}
vector<Object>::const_iterator it2 = vec.begin();
for (; it2 != vec.end(); it2++)
{
//常性迭代器只能调动常方法
// cout << it2->Value() << endl;
cout << (*it2).Value() << endl;
//it->Value() += 100;不能修改,只能读
}
内置类型不影响
//推演出x是object类型,因此需要遍历vector容器,需要每次都把当前节点的对象拷贝给x,如果采用引用,就可以直接操纵vector中的对象,完成相应操作。
for (auto x : vec)//x不是迭代器,vector容器,
{
cout << x.Value() << " " << endl;
}
cout << endl;
for (auto& x : vec)//x不是迭代器,vector容器,
{
cout << x.Value() << " " << endl;
}
cout << endl;
for (const auto& x : vec)
内置类型:不使用引用,直接将1拷贝给x
int arr[] = { 1,2,3,4,5 };
for (auto x : arr)
{ //直接打印
cout << x << endl;//数组也可以被认为是一种容器
}
使用引用:取的是1的地址
int arr[] = { 1,2,3,4,5 };
for (auto &x : arr)
{ //需要下地址,找到其值
cout << x << endl;//数组也可以被认为是一种容器
}
const修饰的是整个迭代器,修饰的是it3本身
所以其指向的值可以变,但是其本身不能变
是否是使用引用和const,取决于使用目的。容器中的数据是否需要修改,是内置类型还是设计类型,等等。
const vector<Object>::iterator it3 = vec.begin();
for (; it3 != vec.end(); it3++) //const修饰的是整个迭代器,修饰的是it3本身 it3++ error
{ //所以其指向的值可以变,但是其本身不能变
cout << it3->Value() << endl;
it3->Value() += 10;
}
void reserve(size_type new_cap);
增加vector的容量到大于或等于new_cap,若new_cap大于当前capacity(),则重新分配空间,将原来数据拷贝构造过去,如果小于capacity(),则不处理。
int main()
{
vector<Object> vec = { Object(10),Object(20),Object(30),Object(40) };
cout << vec.size() << endl;
cout << vec.capacity() << endl;
vec.reserve(10); //如果大于原本的容量。重新申请空间,并将原来容器中的对象,调用拷贝构造,拷贝到新的空间。
cout << vec.size() << endl;
cout << vec.capacity() << endl;
}
如果在使用reserve()时, enw_cap大于capacity,需要重新申请空间,那么迭代器的指向原有空间会被析构,造成迭代器失效。
int main()
{
vector<Object> vec = { Object(10),Object(20),Object(30),Object(40) };
cout << vec.size() << endl;
cout << vec.capacity() << endl;
vector<Object>::iterator it = vec.begin();
Object& obj = vec.back();
vec.reserve(10);
cout << vec.size() << endl;
cout << vec.capacity() << endl;
}
如果resize()的参数大于原来的capacity,那么
vec.resize(10);
vec.resize(2);//会将10个对象,后面8个对象全部析构掉
void assign(size_t count, _Ty());
这个函数和上面两个的不同之处是:
int main(void)
{
vector<Object> vec = { Object(10), Object(20), Object(30),Object(40) };
cout << vec.size() << endl;
cout << vec.capacity() << endl;
vec.assign(10, Object(100));//构建新对象,delete 原来的对象,,拷贝构造到vector容器中,拷贝10次
cout << vec.size() << endl;
cout << vec.capacity() << endl;
return 0;
}
int main(void)
{
vector<Object> vec = { Object(10), Object(20), Object(30),Object(40) };
cout << vec.size() << endl;
cout << vec.capacity() << endl;
{
vector<Object> tmp(vec);
tmp.swap(vec);
}
cout << vec.size() << endl;
cout << vec.capacity() << endl;
return 0;
}
1.调用拷贝构造函数将vec的中的对象拷贝到tmp
2.使用swap,将tmp和vec中的first,last,end进行交换。
3.块作用域结束,释放tmp中的对象,以及空间。
完成容量的缩小。(必须使用块作用域)
vector的数据老是搬家,非常的危险。
int main(void)
{
vector<Object> vec = { Object(10), Object(20), Object(30),Object(40) };
cout << vec.size() << endl;
cout << vec.capacity() << endl;
vec.reserve(10);
vector<Object>::iterator it = vec.begin();
cout << it->Value() << endl;
vec.push_back(Object(40));
cout << it->Value() << endl;
return 0;
}
如果没有一开始就给vec增容,就会导致插入数据时,增容,导致迭代器失效。和reserve()的原因一样,it所指的原空间释放。
由于插入数据时没有空间,就需要扩容,原空间释放。迭代器失效。
int main(void)
{
vector<Object> vec = { Object(10), Object(20), Object(30),Object(40) };
cout << vec.size() << endl;
cout << vec.capacity() << endl;
vec.reserve(10);
vector<Object>::iterator it = vec.begin();
cout << it->Value() << endl;
vec.insert(it, Object(90)); //均是调用拷贝构造函数,将Object对象拷贝到vec中,it所指的位置。
vec.insert(it, { Object(70),Object(80) });
//可以初始化列表方式进行初始化。
cout << it->Value() << endl;
return 0;
}
使用定位new,创建对象。
如下:
template<class T,class<...Arg>>
void Make(T* p,Arg...arg)
{
new(p) T(std::forward<Arg...>(arg)...);
}
emplace_back(100)
将100作为实参,在vector容器中的插入点,调用Object的构造函数,直接初始化,创建对象。
而push_back 是隐式的调用拷贝构造,将obj无名对象拷贝到vector的插入点。然后将拷贝构造析构掉。
int main(void)
{
vector<Object> vec = { Object(10), Object(20), Object(30),Object(40) };
vec.reserve(10);
cout << vec.size() << endl;
cout << vec.capacity() << endl;
vec.emplace_back(100);
cout << vec.size() << endl;
cout << vec.capacity() << endl;
return 0;
}
#emplace_back和push_back相比,前者的效率更快。
前者使用定位new在vector的插入节点,调用构造函数,创建对象
后者,调用拷贝构造将Object对象,将无名对象拷贝到vector容器中。
提前增容,就不会因为容量不足导致扩容,让先前的空间被析构。