14.4.1 旁白:设计上的考虑
到目前为止,一切顺利,但为什么我们不在operator[]()中实现范围检查呢?与我们的实现类似,标准库vector在operator[]()也中没有进行范围检查,而是在at()中提供了范围检查。在本节中,我们将解释这样做的意义所在。主要有以下四个方面因素:
1.兼容性:在C++具有异常机制之前,人们就已经在使用不带范围检查的下标操作了。
2.效率:你可以在一个不进行范围检查但性能更优的运算符基础上实现一个进行范围检查的运算符,但你不能在一个进行范围检查的运算符基础上实现性能更优的运算符。
3.约束:在一些环境中,异常是不可接受的。
4.检查的可选性:C++标准并没有规定你不能对vector进行范围检查,所以如果你希望进行检查,可选择能够进行范围检查的实现。
14.4.1.1 兼容性
人们总是希望他们以前的代码能够正常运行。例如,如果你编写了一百万行的代码,为在这些代码中正确使用异常而重写代码是一个浩大的工程。我们可能会认为完善这些代码是有意义的,但我们并不是要为此付出时间和金钱的人。而且,已有代码的维护人员常常认为没有进行范围检查的代码原则上是不安全的,但这些特定的代码已经经过了测试,并已使用了很多年,所有错误都已经查找出来了。我们可以对此表示怀疑,但再次强调,我们不是对实际代码做出这种决策并为之负责的人,不应如此武断。在标准库vector引入C++标准之前,自然不可能有代码使用它,但有数百万行代码都使用了很相似的但不带异常处理的vector(准标准),这些代码中的大部分最终都修改为使用标准vector。
14.4.1.2 效率
在极端情况下,范围检查是一种负担,例如网络接口的缓冲区和高性能科学计算中的矩阵。但是,在我们大多数人大多数时间进行的“普通计算”中,范围检查的代价很少值得关心。因此,我们建议应该尽量地使用进行范围检查的vector实现。 ...