什麼是模板

2021-06-06 09:49:37 字數 2686 閱讀 2508

一、什麼是模板?

模板是實現**重用機制的一種工具,實質就是實現型別引數化,即把型別定義為引數。

兩類模板,一是函式模板,二是類模板。

所謂函式模板,就是建立乙個通用函式,其函式型別和形參型別不具體指定,用乙個虛擬的型別來代表。這個通用函式就稱為函式模板。凡是函式體相同的函式都可以用這個模板來代替,不必定義多個函式,只需在模板中定義一次即可。在呼叫函式時系統會根據實參的型別來取代模板中的虛擬型別,從而實現了不同函式的功能。

類模板,與函式模板類似,針對一組類,使得類中的某些資料成員、成員函式的引數、成員函式的返回值,能夠取任意型別(包括系統預定義的和使用者自定義的)。它的作用不是代表乙個具體的、實際的類,而是代表著一組類家族的抽象。

二、模板的語法

1.函式模板: template函式返回型別 函式名稱(函式引數)

template t returnbiger(t& data1,t& data2)

2.類模板:templateclass 類模板名稱

templateclass test

模板類的函式定義與普通類的函式定義類似,記住有兩點區別就行了,第一是在最前面需要加上template,裡面存放形參,可以不跟引數型別(原因就是由於類不是乙個確定的類,所以需要形參),除此兩點之外,就跟普通的類函式定義完全一樣了。

三、模板的使用

模板的使用,就是模板的特化。模板的使用者是編譯器,編譯器最終會將模板編譯成乙個個具體的函式或者具體的類,這個特化發生在編譯期間,當編譯器發現模板被應用時(不是定義)的時候。因此這就要求模板的實現必須在使用點之前,模板的實現只能在標頭檔案中了(這是由於編譯器不知道模板引數的具體型別,無法為其成員函式生成**.編譯器只用在成員函式的呼叫處,才最終知道如何生成**。模板類的成員函式的定義也不能像普通類的成員函式一樣定義在實現檔案中,而是宣告和實現都應該在標頭檔案)。最終生成的**中是不會有函式模板的,有的是通過函式模板生成的某個資料型別的函式。

對函式模板來說,有兩種使用模式,顯式型別引數和隱式型別引數模式

以returnbiger為例,

int n1=10;int n2=20;

returnbiger(n1,n2); //t被int代替

double d1=10;double d2=20;

returnbiger(d1,d2);//t被double代替

returnbiger(20.0,200.1); //t被float代替

上述為隱式例項化。下述為顯式例項化

returnbiger(d1,d2);// t被double代替

returnbiger(n1,n2); //t被int代替

只用遇到上述語句的時候,編譯器才會使用該函式模板,使用傳給自己的資料型別作為實參生成乙個例項函式。如果我們程式中只是定義了乙個函式模板,而沒有去使用它(隱式例項化、顯試例項化)時,是不會有與該函式模板對應的函式定義的。

多說一句,returnbiger(d1,n1)會有什麼結果?編譯器報錯!編譯器按最先遇到的實參的型別隱含地生成乙個模板函式,並用它對所有模板函式進行一致性檢查,結果發現n1不是double型,因此報錯。

對類模板來說,與函式模板不同的:函式模板的例項化可以由編譯器在處理函式呼叫時自動完成的,而類模板的例項化必須由程式設計師在程式中顯式地指定,只能使用顯式模式。可以想象平時我們如何使用乙個類。類是物件的抽象,物件是類的例項,則類模板是類的抽象,類是類模板的例項。即類模板->特定類->類物件,在類模板名之後在尖括號內指定實際的型別名,在進行編譯時,編譯系統就用確定的型別取代類模板中的型別引數t,這樣就把類模板具體化了,或者說例項化了

模板類名字《具體的引數型別》 物件名字, 然後生成的物件就是乙個普通的類物件,如下,其中a1到a4就是由類模板建立的4個普通的類物件

testa1(10);

testa2;

testa3(10);

testa4(10.7);

上述語句的執行結果如下:

constructor implemented outside the class/t的型別為int/輸入值為10

constructor implemented inside the class/t的型別為int/輸入值為空

constructor implemented outside the class/t的型別為double/輸入值為10

constructor implemented outside the class/t的型別為float輸入值為10.7

類模板也是給編譯器使用的;只有在**中隱式的或者顯示的使用了模板具體化功能,編譯器在編譯程式時才會使用類模板所定義的「處方」來生產出乙個特定型別的類。只是包含類模板而不去例項化使用它,是不會生產出類定義的。

同時編譯器在需要物件之前,是不會生成類的隱式例項化的:

vector*pt;  //是乙個指標,而不需要乙個物件,所以這裡沒有生成vector的類定義

pt = new vector;//現在需要乙個該類的物件,所有這時編譯器會使用vector模板生成vector類 定義

四、其它問題

模板中的typename關鍵字與class關鍵字通用。

c++中,函式模板與同名的非模板函式過載時,應遵循下列呼叫原則:非模板函式最優先,顯式具體化函式次之,模板函式最後適配。

模板功能應用的典型是通過一系列模板類形成的完整類庫,特別是stl和atl。標準c++庫(stl)提供了很多可重用和靈活的類及演算法,而atl則是使用c++進行com程式設計的事實標準。模板相當於特殊的巨集,泛型技術就是寫於型別無關的**,而stl就是模板和泛型技術的結合了。

什麼是模板模式 Template

世界上並沒有完美的程式,但是我們並不因此而沮喪,因為寫程式就是乙個不斷追求完美的過程。意圖在方法中定義一套處理事務的通用邏輯,某些步驟交由子類實現。主要作用還是 復用。類圖 例項 inte ce tmp static abstract class abstmp implements tmp abst...

什麼是徽標LOGO模板

什麼是徽標logo模板?徽標模板logo是一組向量影象 型別元素和圖示或圖形,可以幫助您快速建立半自定義徽標 logo。模板可能包含單個設計元素,也可能是包含多個元素的包,您可以在建立徽標logo設計的過 程中混合搭配它們。雖然有豐富的標誌模板可用,尋找一些容易定製的東西,新增你的專案特徵元素,這樣...

C 模板 什麼是特化?學習筆記

參考 ibm編譯器中國開發團隊部落格 其中幾個比較好的例子,下面的class 都可以換成 typename,向後相容性比較好。而且typename是較class更加新的標準,具體class 可能導致的問題可見這篇文章,講的特別詳細 知無涯值c typename struct t1 struct t2...