第四周的課程繼續介紹標準庫的內容,本週主要介紹了stl中的演算法和介面卡。詳細講解了迭代器中的traits如何幫助演算法獲得更高的效能,也介紹了介面卡如何通過改造其適配物件,使適配物件取得所需的特殊行為。這一部分的內容比較複雜,重點放在演算法和介面卡的使用上,而不是構造上。
一、演算法與迭代器
1.演算法的基本形式
在stl中,演算法主要是以模板函式的形式存在,在呼叫時,需要向模板函式中傳入迭代器以及需要進行的處理函式指標or仿函式。在演算法呼叫時,對不同型別的資料結構,可以使用不同的演算法進行計算,這樣可以提高程式效率。因此,迭代器中會記錄自身的相關資訊,供演算法在呼叫時進行查詢使用。演算法所能知道的所有資訊都是來自於迭代器。
2.迭代器的分類
迭代器按照上圖的繼承體系分為5個類別,分別為:
• output_iterator_tag:只寫迭代器,只能寫資料和向後移動。
• input_iterator_tag:唯讀迭代器,只能讀資料和向後移動。
• forward_iterator_tag:單向迭代器,可讀可寫,只能向後移動。
• bidirectional_iterator_tag:雙向迭代器,可讀可寫,可向前或者向後移動。
• random_access_iterator_tag:隨機迭代器,可讀可寫,可以在常數時間內隨機訪問範圍內的任意元素。
3.迭代器分類對演算法的影響
主要體現在兩方面,一是部分演算法只能傳入特定迭代器,其他迭代器傳入會報錯或者執行效率非常低,比如sort函式便只能傳入隨機迭代器。二是演算法對於特定的迭代器可能有更加快速的計算方法,如distance函式對於普通的迭代器只能使用「++」一步一步去計算兩個迭代器的距離,但是對於隨機迭代器,該演算法便可以直接呼叫「-」計算距離,效率更高。那麼,演算法是如何實現這種區分的呢?
如圖,演算法在執行時會呼叫乙個輔助函式,這個輔助函式往往有幾個過載版本,過載版本的不同的引數對應著一餓tag型別,主呼叫函式通過建立乙個臨時的tag型別實現函式根據迭代器型別決定不同的演算法實現方法。
二、仿函式
仿函式是一種特殊的class或者struct,它通過過載()運算子來模擬函式指標的行為。在stl中,如果仿函式需要應用在函式介面卡中,則需要繼承對應的函式介面卡類。如下圖所示:
繼承了介面卡類後,函式介面卡便可以使用該型別萃取出對應的引數,用於檢查引數型別等工作,具體方式將在介面卡部分介紹。
三、介面卡
在stl中有多種型別的介面卡,所有型別的介面卡都是使用「內涵」的方式實現的。
1.容器介面卡
典型的容器介面卡包括stack、queue等,在容器部分已經介紹了,因此在此不作過多說明。
2.函式介面卡
函式配適器是用於改變函式行為的配適器類,常見的函式配適器有引數繫結函式、否定函式等。前面提到過,如果乙個仿函式如果需要能夠被函式配適器配適,則需要繼承包含引數重新命名的基類。這是因為,在函式配適器中,需要通過基類來萃取傳入的仿函式的引數資訊。萃取的原理與traits類似。
3.迭代器介面卡
迭代器介面卡通過過載對應的成員函式,改變迭代器的行為。最典型的迭代器配適器是反向迭代器。
反向迭代器的原理是要模擬反向進行的迭代器,其實現的關鍵是成功的模擬出迭代器前閉後開的特徵。因為反向迭代器常常用於將特定區間進行反向處理,因此這一點十分重要。其模擬效果如下圖所示:
另乙個比較典型的迭代器配適器是inserter配適器,這個迭代器主要應用於copy函式中。我們知道,正常的copy函式是將前兩個迭代器引數區間內的元素複製到以第三個迭代器開頭的一片空間中,在copy演算法內部,直接將目標區域的迭代器所指區域的記憶體覆蓋,不會再額外分配記憶體,因此演算法原始的複製方式會存在一定的安全隱患。如果使用inserter配適器修飾迭代器,再呼叫copy函式,inserter會在迭代器所指的位置後分配空間來儲存複製過來的元素。實現這一功能是通過過載函式實現的。
上圖展示了copy內部的核心函式內容,可見,要實現上述的內容,需要過載幾個函式,分別為*,=,++,以及拷貝建構函式。
上圖展示了一些內部的實現細節,在inserter內部維持了對容器和迭代器的指標,這是為了在賦值時使用容器的inserter函式插入對應資料。
4.兩個特殊的配適器
在stl中有兩個十分特別的配適器,ostream_iterator和istream_iterator。這兩個配適器可以封裝輸出流和輸入流,通過呼叫copy函式將迭代器區間內的資料列印到流中,或者將流中的內容複製到迭代器中。這兩個配適器模擬了迭代器的行為,但是本身卻不是迭代器配適器。因此可以說是非常特殊的配適器。其實現方法與前面的inserter類似,以下有其關鍵源**:
博覽網 設計模式 第二週課程筆記
本週接著介紹詳細的具體的設計模式,包括工廠方法 抽象工廠模式 原型模式 構建器 門面模式 模式 介面卡和中介者。一 工廠方法 1.應用情景 在軟體系統中,經常面臨著物件建立的工作 由於需求的變化,需要建立的物件的具體型別經常發生變化。2.解決方案 在軟體中,可以通過將new封裝到工廠類的create...
第四周課程總結 試驗報告
j a實驗報告 班級 電腦科學與技術二班 學號 20188429 姓名 羅璿哲 完成時間 2019 9 20 評分等級 實驗二 j a簡單類與物件 實驗目的 掌握類的定義,熟悉屬性 建構函式 方法的作用,掌握用類作為型別宣告變數和方法返回值 理解類和物件的區別,掌握建構函式的使用,熟悉通過物件名引用...
第四周課程總結 試驗報告(二)
一 實驗目的 1 掌握類的定義,熟悉屬性 建構函式 方法的作用,掌握用類作為型別宣告變數和方法返回值 2 理解類和物件的區別,掌握建構函式的使用,熟悉通過物件名引用例項的方法和屬性 3 理解static修飾付對類 類成員變數及類方法的影響。二 實驗內容 1.寫乙個名為rectangle的類表示矩形。...