2.不要试图编写独立于容器的代码


STL本身就是以泛化原则作为基础:

  • 数组被泛化为“以包含对象的类型”为参数的容器
  • 函数被泛化为“以使用的迭代器的类型”为参数的算法
  • 迭代器被泛化为“以其指向的对象的类型”为参数的迭代器

有人可能会试图去开发某种程序,它对任何容器都适用,而这是无必要也是不可能的。不同容器应用场合不同,其特性也不同,我们无法再次对其泛化。
但是,我们也许会在某一天发现自己选取的容器并非最佳容器,所以我们试图去改变它。这个时候封装技术就显得很有必要。


封装技术最简单的实现方式就是使用类型定义typedef。具体来说,假设原有代码如下:

1
2
3
4
5
class Widget {...};
vector<Widget> vw;
Widget bestWidget;
... // 给bestWidget一个值
vector<Widget>::iterator i = find(vw.begin(), vw.end(), bestWidget);//寻找等值者

这一种写法相当常见,但下一种更好:
1
2
3
4
5
6
7
class Widget { ... };
typedef vector<Widget> WidgetContainer;
typedef WidgetContainer::iterator WCIterator;
WidgetContainer cw;
Widget bestWidget;
...
WCIterator i = find(cw.begin(), cw.end(), bestWidget);

最明显的一个好处就是更换容器时代码无需发生改动。


当然,类型定义只是词法上的修改,它并未增加什么功能。如果我们不希望让用户得知我们真正使用的容器,那我们则需要使用class来完成。要想减少在替换容器后需要修改的代码,我们可以把容器隐藏在一个class中,并且尽量减少通过类接口(而使外部)可见的,与容器相关的信息。
举例而言,如果我们试图编写一个顾客列表,不直接使用list,而是新建一个customerlist类,并把list隐藏于私有部分,其具体实现可以如下所示:

1
2
3
4
5
6
7
8
class CustomerList {
private:
typedef list<Customer> CustomerContainer;
typedef CustomerContainer::iterator CCIterator;
CustomerContainer customers;
public: // 通过该接口限制list的可见性
...
};

这样既保证了list的私密性,也使代码易于修改。