前言
? ? ? ?"打牢基礎,萬事不愁" .C++的基礎語法的學習
引入?
? ? ? ? STL是標準模板庫,類模板主要是用來做容器的,所以個人理解:標準模板庫是"標準容器庫".容器是STL的核心 .以<C++ Prime Plus> 6th Edition(以下稱"本書")內容理解容器.
類模板內容回顧
?????????類模板把數據類型---class類型或基本類型作為參數傳入,設類型為T,則可以把T*(指針),T**(雙重指針),?T a[](數組)作為類模板屬性
容器概念
? ? ? ? 本書內容解讀
? ? ? ? 寫在前面的話:本節所有的"容器"都要替換成"STL容器"去理解.
? ? ? ? 1>本書P695第三段."它是一個概念化的抽象基類,是因為容器類并不真正使用繼承機制,換句話說,容器概念指定了所有STL容器類都必須滿足的一系列要求"
? ? ? ? ----是抽象基類,但不真正使用繼承機制,讀起來還是很拗口.既然他不要求繼承,就不要想繼承吧,問題不大.容器概念指定了所有STL容器類都必須滿足的一系列要求.估計所有STL容器類都定義了Iterator迭代器作為內部類,算一種表現.C++基礎語法:STL之迭代器-CSDN博客
? ? ? ? ?2>第四段:容器是存儲其他對象的對象。被存儲的對象必須是同一種類型的,它們可以是OOP意義上的對象,也可以是內置類型值。存儲在容器中的 數據為容器所有,這意味著當容器過期時,存儲在容器中的數據也將過期(然而,如果數據是指針的話,則它指向的數據并不一定過期)
?????????----容器的概念:存儲其他對象的對象.被存儲對象必須是同一類型,是OOP對象,內置類型,指針類型都可以.
? ? ? ? 3>第五段:不能將任何類型的對象存儲在容器中,具體地說,類型必須是可復制構造的和可賦值的。基本類型滿足這些要求;只要類定義沒有將復制構造函數和賦值運算符聲明為私有或保護的,則也滿足這種要求。 C++11改進了這些概念,添加了術語可復制插入(CopyInsertable)和可移動插入(MoveInsertable),但這里只進行簡單的概述
? ? ? ? ----class類型(類類型),有默認復制構造函數和賦值構造函數,也沒有放在私有或保護空間(否則在類作用域外無法調用,如在main函數里不能使用 SomeType a=b;),所以沒有問題.
????????在表16.5 "一些基本容器特征"中,提供了"所有容器都提供某些特征和操作".這里有個問題:所有容器是指STL容器,不包括自定義容器(按上面標題1>所述,應該指STL容器).vector<vector<int> >是允許的,如果自定義一個容器叫element,那么vector<element<int> >是否能用?留待驗證.
? ? ? ? 4>第六段:所有容器都提供的某些特征和操作.
? ? ? ? ?----a和b表示類型為X的值;u表示類型為X的標識符.實際上都表示容器類對象,a和b為已初始化的對象,而u表示尚未初始化的對象.
? ? ? ? 時間復雜度:編譯時間快于固定,固定快于線性時間.理解:線性時間需要訪問容器里每一個元素
? ? ? ? 本書P696中"C++新增的基本容器要求"?用到非常量右值,暫不說明
==============================內容分割線==================================?
????????注意:區分STL容器和自定義容器.自定義容器是自己拿類模板定義的,?除了自身定義的api,不能調用表格16.5內的api.嚴格的說:容器是指STL按照類模板定義的數據集合類."自定義容器"是自定義的類模板,存放某一種數據類型的數據集合的類.
? ? ? ? "容器"是一種概念,并且被STL模板庫所實現,要想使用容器,就必須遵守他的規定.例如:類型必須是可復制構造的和可賦值的.---是對于容器的說明,在上面標題3>
????????.假設建立一個vector<vector<int> >.如果自己也定義一個容器elem,不給他定義elem(const elem&)//復制構造函數和elem operator=(const elem&)//賦值構造函數,那么vector<elem<int> >這個容器建立不起來,或者調用表格api會出問題.? 而本書P613的queuetp.h中的QueueTP可以做.建立一個vector<QueueTP<int> >.筆者目前沒有試過,這段話屬于假設.
? ? ? ? 能不能讓自定義容器調用16.5里的api呢,因為容器沒有繼承機制,如果能進入容器底層(編譯器?)或許可以,但這已經超出本書學習范圍了.如果所用的容器算法不太夠用,可以針對容器類對象,用C++間接開發.
class SecondDevelopment{vector<string> strings; //vector對象傳入類SecondDevelopment
public:etc; //其他,用對象函數處理strings
}
==============================內容分割線==================================??
?序列
? ? ? ? 本書內容解讀?
? ? ? ? STL容器進行了分類,其中序列是其中一個種類,特點是序列元素有確定的順序.
? ? ? ? 1>本書P697第二段:序列還要求其元素按嚴格的線性順序排列,即存在第一個元素、最后一個元素,除第一個元素和最后一個元素外,每個元素前后都分別有 一個元素。數組和鏈表都是序列,但分支結構(其中每個節點都指向兩個子節點)不是。
? ? ? ? ?----數組和鏈表比較熟悉了, 分支結構指的是結點有兩個以上子結點的,比如數據結構中的"二叉樹",他有左結點和右結點,在每個結點后面可以往兩個方向走.? ? ? ?
? ? ? ? 2>表16.7的說明? ? ? ??
? ? ? ? 序列類容器的通用函數,整體來說,內容包括:生成序列容器類對象,插入,刪除
a.clear() //清空序列容器
????????另外表達式中有用迭代器對象做形參的地方,按照容器的通用方法,只有begin()和end()是明確能返回首元素迭代器和超尾迭代器.其他地方的迭代器需要求出來.方法和指針一樣,例如:
/*偽代碼*/
//有序列容器sequence,容器內元素類型T,序列容器對象object;
sequence<T> object; sequence::iterator findIterator(T val){ //查找T類型值所在迭代器
sequence<T>::iterator ptr; //聲明迭代器對象;不寫可以讓編譯器推斷;
for(ptr=object.begin();ptr!=object.end();ptr++){if(*ptr=val)return ptr;}
}
? ? ? ? 本書P697第一段:序列概念增加了迭代器 至少是正向迭代器這樣的要求,這保證了元素將按特定順序排列,不會在兩次迭代之間發生變化.----序列用至少正向迭代器,所以支持"ptr++"和"*Ptr"
? ? ? ? 這段代碼的場景是求出某個值所在迭代器,讓后傳入insert函數或者erase函數中使用
? ? ? ? 3>表16.8說明
????????序列類容器的專用函數,整體來說,內容包括:插入,刪除,查找
? ? ? ? 注意:可選的序列函數是哪些容器能使用.
????????用a[n]查找容器內元素的兩個容器vector和deque,說明用的是隨機訪問迭代器
????????常用的push_back()函數,插入序列容器末尾.
小結
? ? ? ? 區別STL容器和自定義容器.
? ? ? ? 可以從迭代器的"糾結"中解放出來了.STL容器將迭代器使用大大簡化了.迭代器也是為了函數而產生的,api在那里,程序員直接調用,不用管迭代器到底干了什么.?
????????迭代器既是實現也是一種概念,從使用者的角度來說,他增加了"統一性"的同時也增加了類模板的復雜程度.但最值得肯定的一點,程序員從中得到啟發.嘗試自己概念設計和實現.
? ? ? ? STL容器簡化了編程,降低了靈活度并制定了使用規則.自定義容器靈活度高,但從頭做起難度會高一些.使用首選STL容器,有對容器感興趣的,可以自己嘗試容器設計,參考黑皮書<C++編程思想>