目錄
模板
函數模板
顯示實例化
類模板
模板特點
模板
????????模板,就是把一個本來只能對特定類型實現的代碼,變成一個模板類型,這個模板類型能轉換為任何內置類型,從而讓程序員只需要實現一個模板,就能對不同的數據進行操作。模板分為函數模板和類模板
????????模板使用格式:template<typename T1, typename T2,......,typename Tn>;也可以為:template<class T1, class T2,......,class Tn>。
函數模板
????????函數模板,就是用模板來實現一個函數,從而讓這個函數可以供任何內置類型使用,例如下圖:
????????我們定義T為模板,那么T就可以為任何內置類型,當傳入不同類型時,編譯器都會自動對應上。當然下面swap(a,b)和swap(c,d)也不是同個swap函數,而是編譯器根據我們形參的類型,從而把T轉換為形參的類型,然后生成一個swap函數。圖中代碼會生成一個形參是int類型的函數和一個形參是double類型的函數。
????????編譯器根據我們給的類型,在根據函數模板,生成對應類型的函數;這個過程叫模板的實例化。
????????如果swap的兩個傳參不是同個傳參,但函數模板里是同個模板T,就會無法編譯;這時候只能用顯示實例化來強行讓兩個傳參為顯示實例化的類型。
顯示實例化
????????進行模板實例化時,還可以顯示實例化。即使用模板函數的時候,強制后面的形參為我們所要求的類型。使用方法為:函數模板名<類型>(對象1,對象2....);強制讓對象1和對象2為前面<>內輸入的類型。
????????比如下圖,直接用add(a,b)是編譯不過的,但用了顯示實例化就可以強行讓a和b都為int類型,再生成一個int類型的add函數,進行調用。
類模板
????????類模板,就是把模板的類型放入類中,這樣在我們類的對象實例化的時候,就可以自主選擇需要創建的對象的類型。
????????注意:類模板創建對象時必須進行顯示實例化。
????????類模板不能聲明定義分離到兩個文件,在一個文件內進行聲明定義分離時,定義部分要包含域和模板類型,而且在定義的上方要在聲明一次模板。(因為上面聲明的模板,是在class內使用,下面再次聲明的模板是在函數內使用)具體使用方式如下圖所示:
模板特點
????????模板不能聲明定義分離。
????????模板只能定義一行使用一行,當模板被使用于函數或者類中后,不能再放入其他函數或者類中。
????????當模板名字和我們自己定義的函數名沖突時,不會報錯;當我們調用函數時,編譯器會先找有沒有形參對應上的非模板函數,找不到才會實例化模板。但如果使用了顯示實例化則會強制調用模板,進行模板實例化。??
????????模板函數不允許自動類型轉換,如果類型不同,則編譯不了,只能用顯示實例化;但普通函數可以進行自動類型轉換。
????????模板可以具有非類型參數(模板可以變為任何內置類型,內置類型有大有小),用于指定大小,可以根據指定的大小創建動態結構,所以模板可以用來創建動態增大或減小的數據結構。
????????模板運行時不檢查數據類型,相當于類型的宏替換,不保證安全。
????????類模板是一個類家族,模板類是通過類模板實例化的具體類。
????????C++中類模板的聲明格式為template<模板形參表聲明><類聲明>,并且類模板的成員函數都是模板函數。因為模板可以轉為任何類型,所以在類模板中,每個成員函數都有一個this指針代表自己,就會包含這個模板,所以成員函數就是模板函數。比如一個Stack類模板,里面的成員函數一定都是對Stack的數據進行修改操作,而Stack的數據類型是由模板控制的,所以Stack類中的成員函數就都是模板函數。