1 什么是vector?
vector是可变大小的数组序列容器。
和数组一样,它也是连续的,这意味着也可以对它执行下标访问,它的大小是动态变化的,容器能自行处理。
本质上: vector动态的分配数组,当新元素进来时,他可能会将所有的元素整体移到新的一块空间。(这里就是迭代失效的根源)
从效率上来说,这样做效率当然比较慢了,
**
但为什么它跟string类这么相似,还有他存在,而不直接用string类呢?
因为string类是都是以’\0’结尾的 ,而字符数组不一定具有’\0‘所以很不方便,并且string类的一些都有方法其他类型是用不上的,所以我们精简出了vector类。提高效率。
最后注意 vs下增容机制是1.5倍速率,gcc下是2倍速率。
vector构造 函数:
vector();//构造
vector(size_t n,const value& val =value_type())//构造并初始化n个 //val
vector(const vector& v)// 拷贝构造
vector(InputIterator first ,InputIterator last);//迭代器初始化构造
2 vector 迭代器接口
begin()+ end () //正向 begin获取当前位置的迭代器,end获取最后一个位置的下一个位置的迭代器
rbegin ()+ rend() //rbegin获取最后一个位置的的迭代器,rend获取第一个位置的前一个位置的迭代器
3 vector的空间 一些接口
size();//有效长度
capacity()//底层容量
empty()//判空方法 返回值为 bool类型
resize()//改变vector的size;//它可能会影响到容器的capacity
reserve()//申请预留空间//也可能会改变capacity的大小
insert(pos,char a);
assign(size_t , const& v)//对已有的vector改数据
4 vector 的增删查改
push_back()//尾部插入字符
pop_back()//尾部删除字符
find() //find 其实是STL的算法块的
insert(pos ,char c);//任意位置插
erase(pos);任意位置删
swap();//也是STL算法块的
operator[ ];// 获取某个位置的字符 下标访问,错了报异常
opperator at // 也是获取某个位置的字符 错了崩溃
front();返回首位置的解引用(具体字符值)
back()//末位置的解引用(字符值)
begin () 和 end()返回的是迭代器 (指针)
vector的构造和拷贝构造
#define _CRT_SECURE_NO_WARNINGS
#include"iostream"
#include"windows.h"
#include"stdio.h"
#include"vector"
using namespace std;
namespace N
{
class string
{
public:
string(const char* str="")
:_str(nullptr)
,_size(0)
,_capacity(15)
{
}
string(const string& s)
{}
private:
char* _str;
size_t _size;
size_t _capacity;
};
}
int main()
{
string a = "hello";
vector <int> first;
vector<int>second(4,100);
vector<int>second3(second.begin(), second.end());//区间构造
auto it = second3.begin();
while (it != second3.end())
cout << *it++ ;
cout << endl;
//
vector<int>second2 = { 2,3,4 };
vector<int>(third);//拷贝构造
int myints[] = {2,3,4,5};
vector<int>fifth(myints,myints+sizeof(myints)/sizeof(int));
cout << "fifth内的元素为: "<< endl;
//for循环
for (int i = 0; i < fifth.size(); i++)
//std::cout << fifth[i];
std::cout << fifth.at (i);
cout << endl;
//迭代器
//C++98
for (std::vector<int>::iterator it=fifth.begin();it!=fifth.end();++it)
std::cout << *it;
cout << endl;
//c++11
for ( auto it=fifth.begin(); it < fifth.end(); ++it)
cout << *it;
cout << endl;
for (auto& a : fifth)
cout << a;
cout << endl;
int aa[20] = { 2,3,4 };
int& ra = aa[1];
cout << ra << endl;
// int (&rb)[20] = aa;
system("pause");
return 0;
}
vector内元素的打印
#define _CRT_SECURE_NO_WARNINGS
#include"iostream"
#include"windows.h"
#include"stdio.h"
#include"vector"
using namespace std;
namespace N
{
class string
{
public:
string(const char* str="")
:_str(nullptr)
,_size(0)
,_capacity(15)
{
}
string(const string& s)
{}
private:
char* _str;
size_t _size;
size_t _capacity;
};
}
int main()
{
string a = "hello";
vector <int> first;
vector<int>second(4,100);
vector<int>second3(second.begin(), second.end());//区间构造
auto it = second3.begin();
while (it != second3.end())
cout << *it++ ;
cout << endl;
//
vector<int>second2 = { 2,3,4 };
vector<int>(third);//拷贝构造
int myints[] = {2,3,4,5};
vector<int>fifth(myints,myints+sizeof(myints)/sizeof(int));
cout << "fifth内的元素为: "<< endl;
//for循环
for (int i = 0; i < fifth.size(); i++)
//std::cout << fifth[i];
std::cout << fifth.at (i);
cout << endl;
//迭代器
//C++98
for (std::vector<int>::iterator it=fifth.begin();it!=fifth.end();++it)
std::cout << *it;
cout << endl;
//c++11
for ( auto it=fifth.begin(); it < fifth.end(); ++it)
cout << *it;
cout << endl;
for (auto& a : fifth)
cout << a;
cout << endl;
int aa[20] = { 2,3,4 };
int& ra = aa[1];
cout << ra << endl;
// int (&rb)[20] = aa;
system("pause");
return 0;
}
迭代器的失效现象
发生原因:: 在对vector进行扩容时,在底层将会重心将整体元素移动到一个新的地址,所以元素的地址可能发生了
改变,因此在程序中(或循环中)若果再次对上一次的迭代器进行移动(++/–等操作),其实就是对非法地址操作
1 扩容可能会发生 insert push_back; resize() resere() assign(对已有兑进行修改)
2 删除的时候可能会发生 erase substr clear等
1的 解决策略 删除的后重新赋值,赋值的结果将是当前删除对象的下一个元素的地址
2的解决策略 : 扩容之后重新接收 ;接收方式:重新赋值为当前对象的begin() eg: it= v.begin()
int main()
{
//C++11支持的赋值方式
vector <int >v = {1,2,3,4,5,6,7};
std::vector<int>::iterator it = v.begin();
cout << *(it+6) << endl;
//1 插入 push_back
v.push_back(0);
//注意下面这条语句 可能 出错,因为vector的地址很可能已经改变了
//cout << *(it + 6) << endl;
//我们解决策略 注意屏蔽掉上面的代码
it = v.begin();
cout << *(it + 6) << endl;//发现了没 ,这下多完美呀!!
//1 insert
v.insert(v.begin(),'0');
//检测 出现了错
//cout << *(it + 6) << endl;
//解决b
it = v.begin();
cout << *(it + 6) << endl;/*完美*/
//1 resize(),注意resize只有在扩容时才可能发生迭代器失效
cout<<v.capacity()<<endl;//检测当前容量 结果是 10
//扩容
v.resize(11);
it = v.begin();//解决策略
cout << *(it + 6) << endl;
cout << v.capacity() << endl;/*我们发现 vector和 string 底层都是安1.5倍速度扩容 */
//reserve 申请预留空间
v.reserve(12);
it = v.begin();/*解决策略*/
cout << *(it + 6) << endl;
//删除
cout << v.front() << endl;
//bigin() end() 方法 返回的是一个迭代器(指针)
// v.front()返回一个引用 ,也就是说front() back()方法返回一个值
cout << v.back() << endl;
it=v.erase(v.begin());
cout << *it << endl;
system("pause");
return 0;