重读STL

从第一次使用STL到现在也有四年了,说来惭愧,以前一直只是现用现查,还从来没有仔细地读一读STL的文档。前两天偶尔看到一个别人推荐的链接(http://www.sgi.com/tech/stl/),才想起应该看看,一读之下,果然大有收获,不禁慨叹大师就是大师,这STL真是写的出神入化,把C++template发挥到了极致。

 

先说说STLConcept。譬如最基本的一个InputIterator,按照STL的结构,只要满足一些条件的都可以是InputIterator,如能够做++i,能dereference: *i,等等。其实这些概念也可以用一个类来表示,比方定义如下:

class InputIterator

{

       virtual InputIterator& operator++() = 0;

       virtual InputIterator& operator*() = 0;

       ...

}

但是单纯的类结构会使程序很没有灵活性。其它类型的Interator如果要具备InputIterator的属性必须从这个InputIterator派生,写起来非常的awkward。利用template写的STL,如

template<class InIt, class T> InIt find(InIt first, InIt last, const T& val);

只要你给first, last能做++,value type能比较,它就能正确工作。

 

从这里可以看出template在设计通用类、算法的灵活性。为了你的通用类、算法能被最大限度地利用,你应该assume被操作对象最少的属性。但是往往不同的函数要求操作对象应当具备的属性不一样。如果没有template,你就得象MFC那样用一个CObject作为万物之源(所有被操作对象的祖先),而且这个CObject几乎得无所不包;或者你也可以根据具体的函数需要象前面那样定义InputIterator类,ForwardIterator类,RandomIterator类。。。但是这些类的功能之间很可能有overlap,很难将它们的关系理清楚。更不用说C的原始数据类型如指针就无法操作了。

 

再举个活例子吧,也是关于我改写一些通用函数的。以前我有两个函数,分别把文件数据loadvectorstring,最初是这么写的:

 

bool LoadFromFile(const string& filename, vector<char>& data)

{

       fstream is;

       is.open(filename.c_str(), ios::in | ios::binary);

       ... //Get length

       data.resize(length);

       is.read((char*)&data[0], length);

       ...

}

 

bool LoadFromFile(const string& filename, string& content)

{

       vector<char> v;

       if (!LoadFromFile(filename, v)) return false;

       content.assign((const char*)v.begin(), (const char*)v.end());

       return true;

}

 

第二个函数显然没有效率,但如果不想copy code这也是个办法。改写时发现如果用template写,何须管你是vector还是string?看看下面:

 

template<class _S, class _Data> bool LoadFromFile(const _S& filename, _Data& data)

{

       FILE* f = NULL;

       ...

       f = my_fopen(filename.c_str(), attr.c_str());

       ...

       data.resize(length);

       fread((char*)&data[0], 1, length, f);

       ...

}

现在,对这个输入的data的要求只是:

       1. 有一个resize()函数。

       2. 内存数据块连续,且&data[0]返回数据块的起始地址。

这样vector, string就都可以使了。

 

总结:

继续体会STL的精神,进一步发扬光大template

posted on 2004-06-17 17:33  阿呆  阅读(963)  评论(4编辑  收藏  举报

导航