-- template 的用法
在程式設計當中經常會出現使用同種資料結構的不同例項的情況。例如:在乙個程式中
可以使用多個佇列、樹、圖等結構來組織資料。同種結構的不同例項,也許只在資料元素
的型別或數量上略有差異,如果對每個例項都重新定義,則非常麻煩且容易出錯。那麼能
否對同種型別資料結構僅定義一次呢?答案是肯定的,c++提供的類模板(class template
)就可以實現該功能。
一、類模板
類模板是c++提供的一種特殊機制,通過它我們可以定義一種特殊的類(稱為模板類),在類
的定義中可以包含待定的型別引數,在宣告類的例項時,系統會自動根據傳遞的型別生成
使用者想要生成的類例項。下面是用c++實現的乙個簡單的模板類clist的定義。
1 template classclist
2
在這裡,t是型別引數,i是整型常量引數。t和i的實際值是在宣告具體類例項時指定的。
模板類的<>號內可以包括任意個型別引數和常量引數(至少要有乙個引數)。型別引數和
常量引數可以是任何合法的標準型別和使用者自定義型別,包括簡單型別及各種結構體。同
其他類一樣,類成員函式setitem的實現可以在類定義內完成,也可以在類clist定義處實
現:
1 template int clist::setitem(int index, const t &item)2
值得注意的是,在類定義外完成函式實現時,必須以關鍵字template和類模板定義中相同
的參數列(<>號內的)開頭(上例為template),並且範圍分解操作符前的
類名後應跟上模板引數名清單(上例為clist)。另外,與非模板類不同的是,必須將
函式實現包括在呼叫它的每個原始檔中,使編譯器能從函式實現產生**。通常的做法是
將模板類的函式實現也放在定義該類的標頭檔案中,這樣只需在呼叫的原始檔中包含該頭文
件即可。
那麼,如何使用生成特定的類例項呢?我們可以像使用其他類一樣來使用模板類,不過必須
指定模板引數的值。例如採用如下宣告:
clist intlist;
則使intlist成為clist類的例項,每次出現的t引數都換成int, 每次出現的i引數都換成
100。這樣,intlist類中的buffer就是乙個長度為100的整型陣列,setitem和getitem函式
引數是int值的引用。例:
intlist.setitem(0, 5); //給陣列第乙個元素賦為整數5
模板類還可以像其他類一樣可以定義建構函式和析構函式。下面我們以一種簡單的資料
結構——堆疊為例,來說明如何用類模板來構造通用資料結構。
二、 利用類模板實現通用堆疊結構
任何抽象資料結構在計算機中的實現,歸根結底都只有兩種方式:順序儲存(用陣列實現)
,鏈式儲存(用指標實現)。堆疊也不例外,按其實現方式可分為順序棧(用陣列實現)和鏈
棧(用指標實現)。
1. 通用順序棧的實現
因為順序棧中的元素在空間上連續儲存,棧頂的元素位置需要註明,所以構造順序棧的模
板類應該有這樣的一些成員變數:乙個待定型別和長度的陣列buffer,乙個記錄棧頂元素
的陣列下標的整型變數top。堆疊的基本操作主要有:入棧(push)、出棧(pop)、置空(se
tempty)、判斷當前狀態(isempty)等,它們應用模板類的成員函式來實現。作為乙個標準
的類,它還應該有自己的建構函式和析構函式。具有這些功能的模板類,就可以作為乙個
通用的順序棧來使用了。該類的定義如下:
1 template classcarraystacktemp2;
8 ~ carraystacktemp (){};//
析構函式
9void setempty (); //
置空堆疊
10bool isempty(); //
判斷堆疊是否為空
11bool push(t element); //
入棧12
bool pop(t& element);//
出棧13
private:14
t buffer[size];
15int
top;
16 };
與堆疊的基本操作相對應的成員函式的實現如下:
1 template void carraystacktemp:: setempty ()25 template bool carraystacktemp:: isempty ()
69 template bool carraystacktemp:: push (t element10)
1118 buffer[top]=element;
19return
true;20
}21 template void carraystacktemp:: pop (t&element22)
23
根據實際需要,還可以擴充堆疊功能。例如:加入取棧頂元素、求堆疊長度等操作,其方法
如上。2. 通用鏈棧的實現
模板類中允許使用指標和定義自己的結構,這就為實現鏈式結構提供了保證。這裡採用一
個單鏈表來實現堆疊,棧頂指標指向鍊錶的第乙個結點,入棧和出棧均在鍊錶的頭進行。
該模板類的定義如下:
1 template classclinkstacktemp2;
10 ~clinkstacktemp(){}; //
析構函式
11//
定義結點結構
12struct
node13;
18void setempty(); //
置空堆疊
19bool isempty(); //
判斷堆疊是否為空
20bool push(t element); //
壓入堆疊
21bool pop(t& element);//
彈出堆疊
22private
:23 node*top;
24 };
該類的成員函式實現如下:
1 template void clinkstacktemp ::setempty()211}12 template bool clinkstacktemp ::isempty()
1316 template bool clinkstacktemp ::push(t element)
1726 template bool clinkstacktemp ::pop(t&element)
27
與順序棧的實現略有不同,鏈棧不必指定棧的容量,其大小可以是近似"無限"的。為了程
序的使用方便,我們同樣可以加入一些增強的功能。
三、 通用堆疊類的使用
通用堆疊類的使用較為簡單,堆疊類的例項就是乙個可以方便使用的堆疊。對堆疊的操作
都是通過類的成員函式來實現的。使用的具體步驟如下:
1. 在要使用堆疊類的程式**的檔案開頭包括模板類及其成員函式的定義。
2. 類的例項化,可宣告成變數,也可以宣告它的指標,如:
carraystacktemp intstack; //生成乙個長度為100的int型堆疊
//生成乙個元素為record型的堆疊,record為自定義結構
clinkstacktemp * recordstack;
recordstack=new clinkstacktemp;
應注意在定義順序棧時,必須指定棧的大小,而鏈棧則不必。另外在指定指標型別和執行
new操作時,必須對模板引數賦值,並且前後要一致。
3. 對堆疊進行操作,如:
intstack.push(3); //將整數3入棧
recordstack.setempty(); //將堆疊置空
無論我們使用哪種堆疊類,對使用者來講都是透明的,操作起來並無差別。
今天看的C primer
1.int s while cin s s sought 等價於 while scanf d s eof 2.懸垂else問題 即if比else多。c 中預設else與最近乙個未匹配的if結合。對於懸垂else問題,有些可以在每個if語句之後都是用花括號,避免混亂和錯誤。這個想法,很不賴啊 3.在a...
C Primer 類的多型
一,概述 1 介面的多種不同的實現方式即為多型。2 多型性是允許你將父物件設定成為和乙個或更多的他的子物件相等的技術,賦值之後,父物件就可以根據當前賦值給它的子物件的特性以不同的方式運作。簡單的說,就是一句話 允許將子類型別的指標賦值給父類型別的指標。多型性在c 中都是通過虛函式 virtual f...
c primer 的學習心得
學習 c primer 3rd 中文版 有乙個多月了,沒有按順序看,因為以前看過 錢能的 那本 c 程式設計 就從網上下了電子版的看,pdf的,可以在上面直接做筆記,有些章節列印出來看,同時參考了 c 程式設計金典 本來是打算看 thinking in c 的,看到第三章,就看不懂了,乾脆就,找了本...