概念:vector表示对象的集合,其中所有对象的类型都相同。集合中的每个对象都有一个与之对应的索引,索引用于访问对象。
如果想用到vector,就必须include<vector>和 using namespace std
vector是一个类模板,vector是模板并非类型,由vector生成的类型必须包含vector中元素的类型。vector<int>
1.1定义和初始化vector对象
初始化vector对象的几种方法:
vector<T> v1 v1是一个空vector,它潜在的元素是T类型的,执行默认初始化
vector<string> svec; //默认初始化,svec不含任何元素
vector<T> v2(v1) v2中包含有v1所有元素的副本
vector<int> ivec;//初始状态为空
//在此处给ivec添加一些值
vector<int> ivec2(ivec);//把ivec的元素拷贝给ivec2
vector<T>v2 = v1 等价于v2(v1), v2中包含有v1所有元素的副本
vector<int> ivec3=ivec;//把ivec的元素拷贝给ivec3
vector<string>svec(ivec2); //错误:svec的元素是string对象,不是int
vector<n,val> v3 v3包含了n个重复的元素,每个元素的值都是val
vector<int> ivec(10,-1);//10个int类型的元素,每个都被初始化为-1
vector<n> v4 v4包含了n个重复地执行了值初始化的对象
vector<int> ivec(10); //10个元素,每个都初始化为0
vector<T> v5{a,b,c...} 列表初始化vector对象 v5包含了初始值个数的元素,每个元素被赋予相应的初始值
vector<string> v1{“a”,”an”,”the”};//列表初始化
vector<T> v5 = {a,b,c...} 等价于v5{a,b,c}
1.2向vector对象中添加元素
对vector对象来说,直接初始化的方式适用于三种情况:初始值已知且数量较少、初始值是另一个vector对象的副本、所有元素的初始值都一样。然而更常见的情况是:创建一个vector对象时并不清楚实际所需的元素的个数,元素的值也经常无法确定。
push_back把一个值当成vector对象的尾元素“压入”到(push)vector对象的”尾端(back)“。
vector<int> v2;//空vector对象
for(int i = 0;i != 100;i++){
v2.push_back(i);//依次把整数值放到v2尾端
}
1.3其他vector操作
v.empty() 如果v不含有任何元素,返回真;否则返回假
v.size() 返回v中元素的个数
v.push_back(t) 向v的尾端添加一个值为t的元素
v[n] 返回v中第n个位置上元素的引用
v1 = v2 用v2中元素的拷贝替换v1中的元素
v1 = {a,b,c...} 用列表中元素的拷贝替换v1中元素
v1 == v2 v1和v2相等当且仅当它们的元素数量相同且对应位置元素值都相同
v1 != v2
<,<=,>,>= 以字典顺序进行比较
注意:size()返回vector对象中元素的个数,返回值的类型是由vector定义的size_type类型。
要使用size_type,需首先指定它是由哪种类型定义的。vector对象的类型总是包含着元素的类型
vector<int>::size_type //正确
vector::size_type //错误
1.4使用下标运算符访问vector对象的元素
vector<int> v{1,2,3,4,5};
for(auto &i : v){
i*=i;
}
for(auto i:v){
cout<<i<<””;
}
或者
for( i=0;i<iVec.size();i++)
cout<<iVec[i]<<ends;
cout<<endl;
1.5通过迭代器访问vector的元素
查找vector是否含有某个元素
第一种方式:
vector<CardSprite*>::iterator it = _cardDown.begin();
for(;it != _cardDown.end();it++){//遍历查找某张牌
if(*it == cardsp){//找到
_cardDown.erase(it);
break;
}
}
第二种方式:
vector<uint32_t>::iterator findItor = find(_joinClubList.begin(), _joinClubList.end(), iClubId);
if (findItor != _joinClubList.end())//找到
_joinClubList.erase(findItor);
1.6迭代器
通过以上发现,string和vector功能完全一致,比如都可以通过下标运算符访问对象的元素,还有另外一点就是string支持迭代器,vector也支持迭代器
l 使用迭代器
每个类型使用迭代器主要由两个成员begin和end,其中begin成员负责返回指向第一个元素(或第一个字符)的迭代器,而end则返回指向容器(或string对象)”尾元素的下一个位置“的迭代器。也就是说,该迭代器指示的是容器的一个本不存在的”尾后“元素。end成员返回的迭代器常被称作尾后迭代器。特殊情况下如果容器为空,则begin和end返回的容器是同一个迭代器
l 标准容器迭代器的运算符
iter 返回迭代器iter所指元素的引用
iter->mem 解引用iter并获取该元素的名为mem的成员,等价于(* iter).mem
++iter 令iter指示容器中的下一个元素。
--iter 令iter指示容器中的上一个元素
iter1 == iter2 判断两个迭代器是否相等(不相等),如果两个迭代器指示的同一个元素或者它们是同一个容器的尾后迭代器,则相等,反之,不相等。iter1 != iter2
判断string是否为空
1、string s(“some thing”);
if(s == “”){};
2、string s(“some thing”);
if(s.begin() != s.end()){//不为空
auto s = s.begin();//s表示s的第一个字符迭代器
*s = toupper(*s);
}
输出结果为Some thing
l 迭代器类型
拥有迭代器的标准库类型使用iterator和const_iterator来表示迭代器的类型。
vector<int>::iterator it; //it能读写vector<int>的元素
string::iterator it2;//it2能读写string对象中的字符
vector<int>::const_iterator it3;//it3只能读元素,不能写元素
string::const_iterator it4;//it4只能读字符,不能写字符
l begin和end运算符
begin和end返回的具体类型由对象是否是常量决定,如果对象是常量,begin和end返回const_iterator;如果对象不是常量,返回iterator;
vector<int> v;
const vector<int> cv;
auto it1 = v.begin();//it1的类型是vector<int>::iterator
auto it2 = cv.begin();//it2的类型vector<int>::const_iterator
C++11新标准引入了两个新函数,分别是cbegin和cend
,这两个函数也分别返回指示容器第一个元素或最后
auto it3 = v.cbegin();//it3的类型是vector<int>::const_iterator
l 结合解引用和成员访问操作
解引用迭代器可获得迭代器的对象。如果对象的类型恰好是类,就有可能希望进一步访问它的成员。例如,对于一个由字符串组成的vector对象来说,要想检查元素是否为空,令it是该vector对象的迭代器。只需检查it所指字符串是否为空就可以:
(*it).empty(),注意(*it).empty()中的圆括号必不可少。