标准库 vector并不进行范围检查(见31.2.2节)。例如:
void silly(vector<Entry>& book){int i=book[ph.size()].number; //book.size()越界//...}
这个初始化操作有可能将某个随机值存入i中,而不是产生一个错误。这并不是我们所期望的,而这种越界错误又非常常见。因此,我通常使用 vector的一个简单改进版本,它增加了范围检查:
template<typename T>class Vec:public std::vector<T>{public:using vector<T>::vector; //使用vector的构造函数(但名字是Vec);见20.3.5.0节T& operator[](int i){return vector<T>::at(i);}const T& operate[](int i)const //常亮版本,见3.2.1.1节{return vector<T>::at(i);}};
vec继承了 vector除下标运算符之外的所有内容,它重定义了下标运算符来进行范围检查。 vector的at()函数同样负责下标操作,但它会在参数越界时抛出一个类型为 out of range的异常(见2.4.3.1节和31.2.2节)。
对于一个Vec对象来说,越界访问会抛出一个用户可捕获的异常,例如:
void checked(Vec<Entry>& book){try{book[book.size()]={"joe",999999}; //会抛出一个异常//...}catch(out_of_range){cout<<"range error/n";}}
这段程序会抛出一个异常,然后将其捕获(见2.4.3.1节和第13章)。如果用户不捕获异常,则程序会以一种定义良好的方式退出,而不是继续执行或者以一种未定义的方式终止。一种尽量弱化未捕获异常影响的方法是使用以try-块作为main()函数的函数体。
例如:
int main(){try{//你的代码}catch(out_of_range){cerr<<"rang error/n";}catch(...){cerr<<"unknowm exception throw/n";}}
这段代码提供了默认的异常处理措施。当我们未能成功捕获某些异常时,就会进入默认异常处理程序,在标准错误流cerr上打印一条错误消息(见38.1节)。
某些C++实现提供带范围检查功能的 vector(例如,作为一个编译选项提供),从而免去你定义Vec(或等价的类)的麻烦。
