C 泛型基礎

2021-07-22 09:24:24 字數 3630 閱讀 5139

標籤: c++

演算法iterator

資料結構

algorithm

class

2011-08-10 16:52

21162人閱讀收藏 

舉報

c/c++(17)

泛型的基本思想:

泛型程式設計(generic programming)是一種語言機制,通過它可以實現乙個標準的容器庫。

像類一樣,泛型也是一種抽象資料型別,但是泛型不屬於物件導向,它是物件導向的補充和發展。

在物件導向程式設計中,當演算法與資料型別有關時,物件導向在對演算法的抽象描述方面存在一些缺陷。

比如對棧的描述:

class stack

如果把上面的偽**看作演算法描述,沒問題,因為演算法與引數型別無關。但是如果把它寫成可編譯的源**,

就必須指明是什麼型別,否則是無法通過編譯的。使用過載來解決這個問題,即對n種不同的引數型別寫n個

push和pop演算法,這樣是很麻煩的,**也無法通用。

若對上面的描述進行改造如下:

首先指定一種通用型別t,不具體指明是哪一種型別。

class stack《引數模板 t>

這裡的引數模板t相當於乙個佔位符,當我們例項化類stack時,t會被具體的資料型別替換掉。

若定義物件s為statc型別,在例項化s時若我們將t指定int型則:

這時候類s就成為:

class s

這時我可以稱class stack《引數模板 t>是類的類,通過它可以生成具體引數型別不同的類。

泛型在c++中的應用:

泛型在c++中的主要實現為模板函式和模板類。

通常使用普通的函式實現乙個與資料型別有關的演算法是很繁瑣的,比如兩個數的加法,要

考慮很多態別:

int add(int a,int b)

float add(float a,float b)

。。。。

雖然在c++中可以通過函式過載來解決這個問題,但是反覆寫相同演算法的函式是比較辛苦的,

更重要的是函式過載是靜態編譯,執行時占用過多記憶體。

在此我們可以用c++的模板函式來表達通用型的函式,如下:

template// 模板宣告

t add(t a,t b)  // 注意形參和返回值的型別

這時c++編譯器會根據add函式的引數型別來生成乙個與之對應的帶具體引數型別的函式並

呼叫。例如:

#include

using namespace std;

template

t add(t a,t b)  //注意形參和返回型別

void main()

template  t1 fun(t1, t2, int )

template 

t1 fun(t1, t2, int )

template  t1 fun(t1, t2, int )

c++模版類的語法

template 

class 類名

成員的實現…

例如://類宣告部分,有兩個模板引數t1,t2

template 

class a

//類實現部分

template 

int a:: fun1(t1 x, int y )

template 

t2 a:: fun2(t1 x, t2 y)

//使用類a

int main( )

由上例可以看出, 類模板引數t1,t2對類的成員變數和成員函式均有效。

在c++程式設計中,當你要實現的乙個類的某些成員函式和成員變數的演算法

資料型別有關,可以考慮用類模板。c++版的資料結構演算法大都用類模板實現。

類模板的性質

1) 類模板不是真正的類,它只是c++編譯器生成具體類的乙個模子。

2) 類模板可以設定預設模板實參。

c++ stl簡介

stl(standard template library,標準模板庫)是c++對泛型程式設計思想的實現,最早是惠普實驗室開發的。

在被引入c++之前該技術就已經存在了很長的一段時間。後來stl成為ansi/iso c++標準的一部分。各個

c++廠商也有各自相應的模板庫,這些庫效率可能很高,但可移植性不一定好。

stl廣義上分為三類:algorithm(演算法)、container(容器)和iterator(迭代器),幾乎所有的**都採

用了模板類和模板函式的方式,這相比於傳統的由函式和類組成的庫來說提供了更好的**重用機會。

在c++標準中,stl被組織為下面的13個頭檔案:、、、、、

、、、、、、和。

1) 演算法(algorithm)

stl提供了大約100個實現演算法的模版函式,演算法部分主要由標頭檔案,和組成。

是所有stl標頭檔案中最大的乙個,它是由一大堆模板函式組成的,其中常用到的功能範圍涉及到比較、

交換、查詢、遍歷操作、複製、修改、移除、反轉、排序、合併等等。

體積很小,只包括一些簡單數**算的模板函式。

中則定義了一些模板類,用以宣告函式物件。

2)  容器(container)(又稱集合collection)

在實際的開發過程中,資料結構本身的重要性不會遜於操作於資料結構的演算法的重要性,當程式中存在著對時間要

求很高的部分時,資料結構的選擇就顯得更加重要。

通過設定一些模版類,stl容器對最常用的資料結構提供了支援,這些模板的引數允許指定容器中元素的資料類

型,可以將許多重複而乏味的工作簡化。

如下表:

資料結構

實現標頭檔案

向量(vector)

順序性容器

列表(list)

順序性容器

雙佇列(deque)

順序性容器

集合(set)

關聯容器

多重集合(multiset)

關聯容器

棧(stack)

容器介面卡

佇列(queue)

容器介面卡

優先佇列(priority_queue)

容器介面卡

對映(map)

關聯容器

多重對映(multimap)

關聯容器

3)迭代器(iterator)

迭代器是一種允許程式設計師檢查容器內元素,並實現元素遍歷的資料型別。c++標準庫為每一種標準容器定義了一種迭代器型別。迭代器型別提供了比下標操作更一般化的方法:所有的標準庫容器都定義了相應的迭代器型別,而只有少數的容器(比如陣列)支援下標操作。因為迭代器對所有的容器都適用,現代c++程式更傾向於使用迭代器而不是下標操作訪問容器元素。

迭代器從作用上來說是stl最基本的部分,迭代器在stl中用來將演算法和容器聯絡起來,起著一種黏和劑的作用。幾乎stl提供的所有演算法都是通過迭代器訪問元素序列進行工作的,每乙個容器都定義了其本身所專有的迭代器,用以訪問容器中的元素。

迭代器部分主要由標頭檔案,和組成。是乙個很小的標頭檔案,它包括了貫穿使用在stl中的幾個模板的宣告,中提供了迭代器使用的許多方法, 為容器中的元素分配儲存空間,同時也為某些演算法執行期間產生的臨時物件提供機制,中的主要部分是模板類allocator,它負責產生所有容器中的預設分配器。

C 泛型基礎

泛型的基本思想 泛型程式設計 generic programming 是一種語言機制,通過它可以實現乙個標準的容器庫。像類一樣,泛型也是一種抽象資料型別,但是泛型不屬於物件導向,它是物件導向的補充和發展。在物件導向程式設計中,當演算法與資料型別有關時,物件導向在對演算法的抽象描述方面存在一些缺陷。比...

基礎 C 泛型

msdn 章節內容 ms help 泛型是 2.0 版 c 語言和公共語言執行庫 clr 中的乙個新功能。泛型將型別引數的概念引入 net framework,型別引數使得設計如下類和方法成為可能 這些類和方法將乙個或多個型別的指定推遲到客戶端 宣告並例項化該類或方法的時候。例如,通過使用泛型型別引...

C 泛型基礎

泛型的基本思想 泛型程式設計 generic programming 是一種語言機制,通過它可以實現乙個標準的容器庫。像類一樣,泛型也是一種抽象資料型別,但是泛型不屬於物件導向,它是物件導向的補充和發展。在物件導向程式設計中,當演算法與資料型別有關時,物件導向在對演算法的抽象描述方面存在一些缺陷。比...