14.6.4 使用std::vector
我在前面的一节曾经提到,当涉及保存并操纵可变大小的数组时,我认为几乎没有任何理由忽视std::vector(见32.2.8小节描述的例外情况),并且这也是一些专家的建议[Sutt2000, Stro1997, Meye1996, Dewh2003]。
大多数C++(www.cppentry.com)爱好者都会同意,使用std::vector是我们数组处理问题的解决方案:
- void process_array(std::vector<Base> &ab)
- {
- std::for_each(ab.begin(),ab.end(), . . .); // 处理所有元素
- }
-
- int main()
- {
- std::vector<Base> ab(10);
- std::vector<Derived> ad(10);
- process_array(ab); // Ok
- process_array(ad); // 编译错误
- . . .
-
然而,你的客户代码可能会跟库函数能够处理的情况格格不入。这种解决方案当然是类型安全的,因为std::vector<Base>跟std::vector<Derived>是截然不同的类型,并且它们之间如果不使用某些丑陋的强制转换的话则无法互操作。但是,除此之外,我认为这种解决方案是有缺陷的。
首先,有些情况下数组是必需的,例如,当需要静态存储的数组时,std::vector(或其他"宛若数组"的容器)是无法满足要求的。
其次,数组的元素可能已经保存在其他地方了,或许是作为另一个vector内的一个更大的区间(range)内的一部分。如果我们想要将那个vector的内容的一个子集传递给我们的函数,我们就必须先将它们拷贝出来,然后作为参数传递给相应的函数。最后,如果这是一次可更改操作的话,我们还需要将处理后的结果拷贝回容器。 以上的一连串(繁琐的)做法是因为,与所有标准库容器一样,vector是按值(by value)来存储并操纵元素的。即使在一个真实的系统中,我们可以以某种方式确保数组处理期间的数据一致性,这种做法也是不切实际的。想象一下其性能开销吧!更别提还得考虑异常安全了!