深入理解STL中的vector容器

本文深入探讨了C++ STL中的Vector容器使用误区,特别是通过示例代码解释了reserve与resize的区别,以及如何正确使用operator[]与push_back方法。

本以为对STL已有所了解,没想到昨天初看《Exceptional C++ Style 40》,就被第一章关于STL的部分给难住了。先附上代码,再做讲解。

vector<int> v;

v.reserve(2);
assert(v.capacity() == 2);
v[0] = 1;
v[1] = 2;
for(vector<int>::iterator i = v.begin(); i < v.end(); i++) {
 cout << *i << endl;
}

cout << v[0];
v.reserve(100);
assert(v.capacity() == 100);
cout << v[0];

v[2] = 3;
v[3] = 4;
// …
v[99] = 100;
for(vector<int>::iterator i = v.begin(); i < v.end(); i++) {
 cout << *i << endl;
}
先将各成员函数做一下讲解:
reserve(size_type n) : 设置vector容器占用容量为参数n个单位(n个用于存放数据的缓冲区)。如果n小于当前容器的容量,则此函数设置失败。
resize(size_type n,Type _val) : 设置vector容器容量为参数n个单位。如果n小于当前容器的空间,则调整大小,将容器中超过n的数据删除,
从而保证容器大小为n。如果n大于当前容器的空间,调大容器容量为n,则用_val值添充新添加到容器的值。
capacity() : 返回vector容器占用容量的大小。(与reserve值相同。返回值是容器中所分配的空间,不是容器中实际的元素个数。)
size() : 返回vector容器中当前元素的个数。(小于等于capacity值。只算容器中实际的元素个数,并不是容器中所分配的所有空间。)
operator[size_type _pos] : 如果_pos小于size(),则返回容器中位于_pos的元素。如果_pos大于size(),系统并未定义会产生什么后果。
at(size_type _pos) : 如果_pos小于size(),则返回容器中位于_pos的元素。如果_pos大于size(),系统会抛出std::out_of_range异常
push_back(const Type& _Val) : 将元素_Val插入到容器最后一个位置,如果当前容器可用空间不足,则系统会自动重新分配空间以容纳新的元素。
reserve和resize的相同点为都将容器的容量设为一新值。不同点为,前者添加容器的容量后并未自动添充新元素(size返回值不变),
且如果新容量小于当前容器的容量,则函数调用失败!并不减小原有容器的容量。而后者将容器调整为新值后,如果待调整值大于当前容器的容量,
则自动添充新的元素到容器中调整大小后的可用空间中(size返回值将变大)。如果待调整值小于当前容器的容量,则会将容器超出的元素删除,调整为指定的更小的数目。
OK,言归正传,看看我们出了什么问题?
首先,v.reserve(2);说明容器v有两个可用缓冲区,但此时并未有数据,故size()返回将为0,所以下一句v[0] = 1;(注意,这和c++中普通数组不同!
这不是一般的赋值操作。因为容器没有数据,所以调用operator[]不会返回第1个元素!)将会产生未知的错误,但不会使程序中止。下一句同理。
故再调用for循环则失败(因为容器中无任何元素!)
cout << v[0];又会产生未知错误(容器元素为空)。下一句v.reserve(100);使容器v的缓冲区调整为100,但此时还未有任何数据,size调用仍为空!
故下面对operator[]的调用仍有错误!
因此operator[]只用于修改实际的元素,并不能起到添加新元素的作用。如果要添加新元素,使用push_back方法。
所以如果将上面所有用operator[]赋新值的调用改为push_back方法调用,则程序将会正常运行。
vector<int> v;
 v.reserve(2);
 if(v.capacity() != 2)
  return;
 v.push_back(1);
 v.push_back(2);
 for(vector<int>::iterator i = v.begin(); i < v.end(); i++) {
  cout << *i << endl;
 }
 cout << v[0];
 v.reserve(100);
 if(v.capacity() != 100)
  return;
 cout << v[0];
 v.push_back(3);
 v.push_back(4);
 v.push_back(100);
for(vector<int>::iterator i = v.begin(); i < v.end(); i++) { cout << *i << endl; }
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值