1. 程式人生 > >c++ 泛型程式設計

c++ 泛型程式設計

C++ 泛型程式設計與STL模板庫(1)---泛型程式設計簡介及STL簡介與結構

泛型程式設計的基本概念

  • 編寫不依賴於具體資料型別的程式
  • 將演算法從特定的資料結構中抽象出來,成為通用的
  • C++的模板為泛型程式設計奠定了關鍵的基礎

術語:概念

  • 用來界定具備一定功能的資料型別。例如:
    • 將“可以比大小的所有資料型別(有比較運算子)”這一概念記為Comparable
    • 將“具有公有的複製建構函式並可以用‘=’賦值的資料型別”這一概念記為Assignable
    • 將“可以比大小、具有公有的複製建構函式並可以用‘=’賦值的所有資料型別”這個概念記作Sortable
  • 對於兩個不同的概念A和B,如果概念A所需求的所有功能也是概念B所需求的功能,那麼就說概念B是概念A的子概念。例如:
    • Sortable既是Comparable的子概念,也是Assignable的子概念

術語:模型

  • 模型(model):符合一個概念的資料型別稱為該概念的模型,例如:
    • int型是Comparable概念的模型。
    • 靜態陣列型別不是Assignable概念的模型(無法用“=”給整個靜態陣列賦值)

用概念做模板引數名

  • 很多STL的實現程式碼就是使用概念來命名模板引數的。
  • 為概念賦予一個名稱,並使用該名稱作為模板引數名。
  • 例如

    • 表示insertionSort這樣一個函式模板的原型:

    • 1

      2

      template <class Sortable>

      void insertionSort(Sortable a[], int n);

STL簡介

標準模板庫(Standard Template Library,簡稱STL)提供了一些非常常用的資料結構和演算法

STL簡介

  • 標準模板庫(Standard Template Library,簡稱STL)定義了一套概念體系,為泛型程式設計提供了邏輯基礎
  • STL中的各個類模板、函式模板的引數都是用這個體系中的概念來規定的。
  • 使用STL的模板時,型別引數既可以是C++標準庫中已有的型別,也可以是自定義的型別——只要這些型別是所要求概念的模型。

STL的基本元件

  • 容器(container)
  • 迭代器(iterator)
  • 函式物件(function object)
  • 演算法(algorithms)

STL的基本元件間的關係

  • Iterators(迭代器)是演算法和容器的橋樑。
    • 將迭代器作為演算法的引數、通過迭代器來訪問容器而不是把容器直接作為演算法的引數。
  • 函式物件作為演算法的引數而不是將函式所執行的運算作為演算法的一部分。
  • 使用STL中提供的或自定義的迭代器和函式物件,配合STL的演算法,可以組合出各種各樣的功能。

STL的基本元件——容器(container)

  • 容納、包含一組元素的物件。
  • 基本容器類模板
    • 順序容器
      • array(陣列)、vector(向量)、deque(雙端佇列)、forward_list(單鏈表)、list(列表)
    • (有序)關聯容器
      • set(集合)、multiset(多重集合)、map(對映)、multimap(多重對映)
    • 無序關聯容器
      • unorderedset (無序集合)、unorderedmultiset(無序多重集合)
      • unorderedmap(無序對映)、unordermultimap(無序多重對映)
  • 容器介面卡
    • stack(棧)、queue(佇列)、priority_queue(優先佇列)
  • 使用容器,需要包含對應的標頭檔案

STL的基本元件——迭代器(iterator)

  • 迭代器是泛化的指標,提供了順序訪問容器中每個元素的方法
  • 提供了順序訪問容器中每個元素的方法;
  • 可以使用“++”運算子來獲得指向下一個元素的迭代器;
  • 可以使用“*”運算子訪問一個迭代器所指向的元素,如果元素型別是類或結構體,還可以使用“->”運算子直接訪問該元素的一個成員;
  • 有些迭代器還支援通過“--”運算子獲得指向上一個元素的迭代器;
  • 迭代器是泛化的指標:指標也具有同樣的特性,因此指標本身就是一種迭代器;
  • 使用獨立於STL容器的迭代器,需要包含標頭檔案。

STL的基本元件——函式物件(function object)

  • 一個行為類似函式的物件,對它可以像呼叫函式一樣呼叫。
  • 函式物件是泛化的函式:任何普通的函式和任何過載了“()” 運算子的類的物件都可以作為函式物件使用
  • 使用STL的函式物件,需要包含標頭檔案

STL的基本元件——演算法(algorithms)

  • STL包括70多個演算法
    • 例如:排序演算法,消除演算法,計數演算法,比較演算法,變換演算法,置換演算法和容器管理等
  • 可以廣泛用於不同的物件和內建的資料型別。
  • 使用STL的演算法,需要包含標頭檔案。
  • 例10-1從標準輸入讀入幾個整數,存入向量容器,輸出它們的相反數

STL程式例項

transform演算法的一種實現:

1

2

3

4

5

6

template <class InputIterator, class OutputIterator, class UnaryFunction>

OutputIterator transform(InputIterator first, InputIterator last, OutputIterator result, UnaryFunction op) {

    for (;first != last; ++first, ++result)

        *result = op(*first);

    return result;

}

  • transform演算法順序遍歷firstlast兩個迭代器所指向的元素;
  • 將每個元素的值作為函式物件op的引數;
  • 將op的返回值通過迭代器result順序輸出;
  • 遍歷完成後result迭代器指向的是輸出的最後一個元素的下一個位置,transform會將該迭代器返回

 

本文內容參考自C++語言程式設計(第4版),鄭莉,清華大學出版社