天天看點

【C++】模闆總結

模闆是一種泛型程式設計的機制,也是一種複用的手段。
編譯器調用模闆函數時,編譯器會根據實參的類型,推演出模闆的類型,并再生産相應的代碼。
【C++】模闆總結
根據模闆函數的形參類型的不同,調用函數時編譯器會去找和自己類型更比對的模闆進行推演并執行個體化。

浮點數和類類型不可以作為非類型模闆參數

為什麼需要特化,因為在對不同類型的參數進行一些相同的處理時,如增容,拷貝等,不同類型的處理方式可能有些不同,如string增容時和其他類型就不同,它需要考慮深拷貝,是以要另外處理,這時候就用特化。
全特化 特化所有的模闆,就是制定所有模闆的類型
偏特化 特化部分模闆參數+指定模闆參數是某種特殊的類型 如指針或引用:template<T*>
我們可以用其他容器實作某一個容器,如我們可以用順序變實作stack,也可以連結清單實作stack,那麼可以寫一個模闆類,

這樣我們想要什麼容器實作,就可以在定義時,傳什麼容器。

模闆特化的延伸,提取出類型,提前把處理動作一樣的類型typedef成一個類型,其他自定義的類型就也可以typedef成一個類型去同一個指定的動作。這樣就可以根據提取出來的類型判斷它屬于萃取後的哪種類型,然後進行相應的操作。
如果一個類裡的成員函數對不同類型需要有不同操作的的地方隻有那麼一小塊代碼,如有一個順序表的類,string需要深拷貝,其他内置類型可以淺拷貝。那麼模闆顯然很不劃算,因為隻能對函數或者類進行特化,上面如果要用模闆的話,需要再特化一個相同的類。現在要根據不同類型對部分代碼塊進行相應的操作,這時就需要類型萃取,通過把類型萃取後,在需要不同操作的地方可以通過萃取的這個類型重載這個函數,也可以在函數裡需要不同操作的地方進行if else判斷相應類型來進行相應的操作。
模闆類的成員函數定義放在data.cpp源檔案,聲明放在data.h源檔案,在另外一個main.cpp檔案裡調用使用模闆類調用成員函數則會發生連結錯誤。是以模闆不支援分離編譯
鋪墊: 程式源檔案在執行連結時,如果函數的定義和聲明不在同一檔案,那麼連結時就會去其他.o檔案的符号表裡去找函數定義的處的位址,找到函數定義的位址後,并添加到調用函數處的call指令後面(call fun 0xadd),才能連結成功,才可生生執行程式。 解釋: 因為模闆沒有執行個體化時是不生成相應的代碼的,因為編譯的時候兩個原檔案互不影響,是以沒有執行個體化,是以在連結的時候就找不函數定義的地方,那麼就會出現連結錯誤。

顯式執行個體化,在定義模闆的地方,主動的去執行個體化相應類型的模闆。template class<int>;

把聲明定義都寫在.hpp裡,main.c調用模闆類的函數時就可以了,其實.hpp相當于.h,預處理時就會頭檔案展開在.cpp裡。

繼續閱讀