vector.operator[]和.at元素访问区别
0.引言
1.区别
[]操作符的源码:
reference
operator[](size_type __n)
{ return *(begin() + __n); }
at函数的源码
reference
at(size_type __n)
{
_M_range_check(__n);
return (*this)[__n];
}
at函数多个超出范围的检查
void
_M_range_check(size_type __n) const
{
if (__n >= this->size())
__throw_out_of_range(__N("vector::_M_range_check"));
}
如果出现内存访问越界报错如下(不要问我怎么知道的!):
#operator[]报错
段错误 (核心已转储)
#at()报错
terminate called after throwing an instance of 'std::out_of_range' what(): vector::_M_range_check
2.正确使用
由于at会做边界检查,如果越界,会抛出异常,应用可以try catch这个异常,应用还能继续运行。
结论:使用at时应使用try catch包裹住;而使用operator[]时一定要先检查一下是否越界。
void doTest01() {
try {
std::vector<std::string> vec;
string& i = vec[2];
cout << i.size() << endl;
}
catch (const exception& e) {
cerr << e.what() << endl;
}
catch (...) {
cerr << "error" << endl;
}
};
void doTest02() {
try {
std::vector<std::string> vec;
string& i = vec.at(2);
cout << i.size() << endl;
}
catch (const exception& e) {
cerr << e.what() << endl;
}
catch (...) {
cerr << "error" << endl;
}
};
doTest01()中,try catch不起作用,应用会直接退出。
doTest02()中,会catch异常,应用不会退出。
3.C++11.vector
对于元素增删添加了如下操作:
1.emplace (C++11)在迭代器位置插入元素(emplace使用直接构造函数,insert使用复制构造函数)
2.emplace_front (C++11)在首部添加一个元素
3.emplace_back (C++11)在尾部添加一个元素