重读STL
從第一次使用STL到現在也有四年了,說來慚愧,以前一直只是現用現查,還從來沒有仔細地讀一讀STL的文檔。前兩天偶爾看到一個別人推薦的鏈接(http://www.sgi.com/tech/stl/),才想起應該看看,一讀之下,果然大有收獲,不禁慨嘆大師就是大師,這STL真是寫的出神入化,把C++的template發揮到了極致。
?<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
先說說STL的Concept。譬如最基本的一個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的原始數據類型如指針就無法操作了。
?
再舉個活例子吧,也是關于我改寫一些通用函數的。以前我有兩個函數,分別把文件數據load進vector或string,最初是這么寫的:
?
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。
轉載于:https://www.cnblogs.com/pront/archive/2004/06/17/16499.html
總結
- 上一篇: 答应我不要问TCP三次握手四次挥手
- 下一篇: 一位台湾校长的讲话。学习!!!