一、什么是模板
模板是C++中自動生成代碼的技術,
二、為什么使用模板
問題:實作一個通用的排序演算法,
C語言:通過回呼函式實作,使用者呼叫麻煩,
C++語言:函式多載,需要為多種型別實作一個第一版本,還會導致代碼段增加,
C/C++語言:借助宏函式實作,型別檢查不嚴格,頻繁使用還會增加代碼段,
由于以上原因C++之父在C++中實作了模板技術,既能技術多種類也能兼顧嚴格的型別檢查,能讓程式員編程專注思考業務邏輯而不用關系資料型別,
三、函式模板
1、函式模板的定義
template <typename T1,typename T2,…>
T2 函式名(T1 a1,T2,a2)
{
T1 v1;
T2 v2 = x;
return v2;
}
可以使用任何識別符號作來型別引數,但使用T是俗成約定的,
typedef 也可以換成 class 它們沒有任何區別,
2、函式模板的使用
C++編譯器并不是把函式模板編譯成一個可以處理所有型別的物體,而是根據呼叫者提供的引數,生產不同的函式物體,
根據具體型別帶入函式模板產生函式物體的程序叫實體化,
模板是呼叫時才物體化:
自動實體化:根據呼叫者提供資料型別自動判斷出型別,
手動實體化:func<型別,…>(引數)
模板的型別引數,與函式的引數沒有關系時使用,
模板的引數型別也可以使用默認形參,
3、模板函式的實體化程序
第一個模板函式都會經歷二次編譯,第一次編譯是在實體化之前,檢查模板代碼自身是否正確,第二編譯是在實體化時,把呼叫者提供的型別引數帶入模板中再次檢查模板代碼,
第二次編譯才生成二進制的函式指令,第一次編譯僅僅是在編譯器的記憶體產生一個用于描述模板的資料結構,
4、模板函式自動實體化的限制
1、函式引數與模板引數沒有關系,
2、回傳值型別不能隱式推斷,
5、模板的特化
模板并不適合所有情況,這時可以給特殊型別實作一個正常的函式,
模板函式在實體化之前會先檢查有沒有正常版本的函式,如果有就不會再繼續實體化,因此模板函式與正常函式并不會沖突,
四、類模板
1、類模板的定義格式
template <typename M,typename R,typename A,typename O>
class Test
{
private:
M val;
public:
R func(A a)
{
O a;
}
};
2、類模板的使用
模板類的型別引數不能隱式打斷,也就是不能自動實體化,必須顯式的指定型別引數,
類名<型別> 物件;
類模板的使用分為三個步驟:
1、檢查類模板的語法,如果合法則在編譯器生成一個類的資料結構,
2、將使用者提供的型別引數代入類模板再次檢查語法,如果合法編譯器會將類模板實體化,并生成類物件的創建指令,
3、執行類物件的創建指令,創建出類物件,
注意:對于類的成員函式,并不全部實體化,而是呼叫誰實體化誰(生成二進制指令),
3、類模板的靜態成員
類中的成員要在類中宣告,類外定義(具有const屬性的外除),類模板的靜態成員也一樣,
template
class Test
{
static int val1;
static T val2;
public:
};
templateint Test::val1 = value;
templateT Test:: val2 = value;
4、遞回實體化
模板的引數可以是任何型別,只要該類提供了模板代碼中所需要的功能,
類模板實體化后已經是一種型別了,所以它也只可以當模板的引數,這種實體化叫遞回實體化,
5、類模板的區域特化
當類的成員函式不能通用,需要對特殊型別實作一個特殊版本的成員函式,這叫類的區域特化,必須要在類外實作,
template<> 回傳值型別 類名<特殊型別>::函式名(引數串列)
{
}
6、類模板的全域特化
要針對某種特殊型別對類實作一個特殊版本,這叫作類的全域特化,
template <> class 類名<特殊型別>
{
…
};
7、類模板的默認形參
類模板的引數也可以設定默認引數,用法與函式模板一致(靠右),
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/134649.html
標籤:其他
上一篇:Python爬蟲入門教程 93-100 幫粉絲寫Python爬蟲之【獲取CSDN周榜所有大佬的收費專欄】
下一篇:答研一學生:你的奮斗在哪里?
