详解C++中的vector容器及用迭代器访问vector的方法
vector vector是相同类型对象的集合。集合中的每个对象有个对应的索引。vector常被称为容器(container)。 #include <vector> using std::vector; vector是一个类模版(class template)。C++有函数模版和类模版。模版本身不是函数或类,必须通过指定 类型让编译器去实例化(instantiation)它。比如vector<int> ivec。 最常有的定义vectors的方法如下:
需要注意的是,最常用使用vector的方法就是定义一个起初为空的vector,即vector<T> v,在运行时指定元素。 vector的列表初始化(list initializing) 上面使用花括号(curly brace)的方法是列表初始化,是C++ 11引入的。 vector<string> articles = {"an","a","the"}; 我们看到C++有很多初始化的方式,很多情况下它们是可以互换的,但有些时候初始化的形式是不能换的: 前面提到vector<int> ivec(10)这种只指定元素个数的初始化方法,每个元素是value-initialized。即: vector<int> v1(10); // 10个元素,都是0 vector<int> v1{10}; // 1个元素,是10 vector<int> v1{10,1}; // 2个元素,分别是10, 1 vector<int> v1(10,1); // 10个元素,都是1 需要注意的是,使用{}并不一定就是列表初始化;它表示: 如果可能的话,使用列表初始化。 vector<string> v5{"hi"}; // ok,list initialization vector<string> v6("hi"); // error: cann't construct vector from string lieral vector<string> v7{10}; // has ten default-initialized value. 上面的v7就使用花括号指定个数,而不是列表初始化。 使用push_back方法。 最常用的操作有:
类似的,v.size()返回的类型也是size_type的。需要注意的是,模版类的类型始终是包括元素类型的, vector<int>::size_type // ok vector::size_type // error 关于下标访问,它只能访问已经存在的元素,不会添加。 vector<int> ivec; cout << ivec[0]; // error for (decltype(ivev.size()) ix = 0; ix != 10; ix++) ivec[ix] = ix; // disaster: has no element
使用begin和end成员函数。 // b 指示第一个元素;e 指示最后一个元素的下一个位置 auto b = v.begin(),e = v.end(); 一般我们不必关心迭代器的准确类型,所以直接使用auto。 | 方法 | 解释 | | iter | 返回指示元素的引用 | | iter->mem | 解引用iter,并获取名字为mem的成员,等价于 (iter).mem | | ++iter | 增加iter,指示下一个 | | --iter | 减小iter,指示前一个 | | ==,!= | 比较 | for(auto it = s.begin(); it != s.end() && !isspace(*it); ++it) *it = toupper(*it); 熟悉C或者Java语言的人可能需要习惯C++里面for循环一般都是使用!=结束,而不是使用<。 这是因为,所有的容器的迭代器都定义了!=和==方法;而绝大部份迭代器没有<方法。通过使用!=,我们可以不必 关心处理容器的准确类型。 就像我们不知道vector或string的size_type的准确类型,我们一般也不知道迭代器的准确类型。 vector<int>::iterator it; // 可读,可写 vector<int>::iterator it2; // 可读,可写 vector<int>::const_iterator it3; // 可读,不能写 const_iterator的行为类似一个const指针。就像const指针,const_iterator不能修改所指示的元素。如果 一个vector或者字符串是const的,那么只能使用const_iterator。 auto it3 = v.cbegin(); 解引用和访问成员 当对迭代器解引用时,得到的是其指示的对象。如果该对象是个类类型的,我们可能要访问其的成员。举个例子,一个字符串的vector可能想知道 给定元素是否为空,可以使用(*it).empty()。 自增与自减是所有迭代器都支持的操作。 auto mid = vi.begin() + vi.size() / 2; 需要注意的是,迭代器的相加是不合法的。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |