[導讀] 最近使用C++做些編程,把日常遇到的些比較重要的概念總結分享一下。本文來分享一下模板類的原理,以及為什么需要模板類,使用時的基本要點。
為什么需要模板
比如需要設計一個描述點的類,大致很快可以寫成這樣:
classPoint_F { public: /*默認傳入參數為0,0*/ Point_F(floatx0=0,floaty0=0) :x(x0),y(y0)/*初始化列表*/ {} /*用const修飾函數,表示函數不會修改成員數據*/ floatget_x()const{returnx;} floatget_y()const{returny;} private: /*一般會將數據放在私有區,以對外隱藏*/ floatx; floaty; };
可問題是,在有的場合這點的坐標系有可能不需要浮點,比如界面設計中點往往是整型表示即可,那此時就需要再設計一個整型成員類:
classPoint_I { public: /*默認傳入參數為0,0*/ Point_f(intx0=0,inty0=0) :x(x0),y(y0)/*初始化列表*/ {} /*用const修飾函數,表示函數不會修改成員數據*/ intget_x()const{returnx;} intget_y()const{returny;} private: /*一般會將數據放在私有區,以對外隱藏*/ intx; inty; };
可是在應用代碼中,往往發現對于不同數據成員的應用操作確實基本類似,而且應用代碼往往這兩種(甚至更多成員數據類型)都可能會同時用到,僅僅因為數據類型就需要笨笨的將原代碼在改寫一下,在現代高級語言中,這顯然就比較機械了。
C++中有沒有可能將不同成員數據類型但是其頂層邏輯相同的對象,設計為一個類呢?就比如:
C++模板編程正是為了解決這樣的需求而設計的機制。該機制允許函數或類使用泛型類型(generic type)進行操作。從而,函數或類就可以處理許多不同的數據類型,而無需為每種數據類型重寫相應的類或者函數。
怎么實現的呢?
這里又可以大致分這樣三種情況:
類模板(Class templates)
**成員模板(Member templates) **
函數模板
函數模板其基本語法范式為:
templatefunction_declaration; template function_declaration;
template 為模板關鍵字
比如:
#includeusingnamespacestd; template Tmax(Ta,Tb) { returna>b?a:b; }
又或者寫成如下形式:
#includeusingnamespacestd; template Tmax(Ta,Tb) { returna>b?a:b; }
那么或許有的朋友會任務關鍵字class就意味著自定義類,而typename則是基本數據類型,比如int,float等,這樣理解其實是不對的,從C++編譯器的角度template
對于上面的代碼,或許初使用的朋友還會問,是不是可以隨便傳入類,這有可能編譯不過。為什么呢?你傳入的類需要支持>操作符,如果對于某個類你想使用該函數,而本身不支持>操作符,則需要實現>操作符。
類模板
與函數模板類似,類內部成員數據或者函數的參數或變量會使用,模板關鍵字定義的泛型名。比如:
templateclassPoint_T { public: Point_T(Tx0=0,Ty0=0) :x(x0),y(y0) {} Tget_x()const{returnx;} Tget_y()const{returny;} private: Tx; Ty; };
這小段代碼就回答了之前提出的問題,可以支持不同數據類型的點。
intmain() { Point_Tp1(1,2); Point_T p2(1.1f,2.2f); cout<
以上述簡單例子看,分別構造了整型點p1,以及浮點型點p2,那么究竟怎么做到的呢?為了理解得更清楚,這里將其關鍵匯編代碼段拷貝下來簡要看看:
Point_Tp1(1, 2); 000C1D6C push 2 000C1D6E push 1 000C1D70 lea ecx,[p1] 000C1D73 call Point_T ::Point_T (0C11D1h) Point_T p2(1.1f, 2.2f); 000C1D78 push ecx 000C1D79 movss xmm0,dword ptr [__real@400ccccd (0C7B34h)] 000C1D81 movss dword ptr [esp],xmm0 000C1D86 push ecx 000C1D87 movss xmm0,dword ptr [__real@3f8ccccd (0C7B30h)] 000C1D8F movss dword ptr [esp],xmm0 000C1D94 lea ecx,[p2] 000C1D97 call Point_T ::Point_T (0C1064h)
可見編譯器對不同類型參數實際上做了相應解析,相當于根據用戶程序傳入的參數編譯出相應的多份代碼。所以可以簡單理解成編譯器根據不同泛型實際參數類型生成了相應的處理代碼。而前面所說的模板函數其原理也基本類似。
總結一下
通過些簡單例子,梳理一下模板函數以及模板類的基本概念以及原理,理解了這兩個概念,就比較容易理解成員模板。所謂泛型模板編程,其本質是編譯器針對不同參數類型解析解析生成相應的處理代碼。學會使用模板泛型編程你會發現你會少寫很多代碼,代碼看起來會比較優雅,而其實操作起來也沒有想象中那么難。
原文標題:什么是函數模板、類模板?怎么做到的?
文章出處:【微信公眾號:FPGA之家】歡迎添加關注!文章轉載請注明出處。
審核編輯:彭靜
-
函數
+關注
關注
3文章
4346瀏覽量
62977 -
C++
+關注
關注
22文章
2114瀏覽量
73859 -
代碼
+關注
關注
30文章
4828瀏覽量
69055 -
編譯器
+關注
關注
1文章
1642瀏覽量
49288
原文標題:什么是函數模板、類模板?怎么做到的?
文章出處:【微信號:zhuyandz,微信公眾號:FPGA之家】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
圖紙模板中的文本變量
![圖紙<b class='flag-5'>模板</b>中的文本變量](https://file1.elecfans.com//web1/M00/F4/D5/wKgZoWcy18-AG-szAAJXO8IiHgQ099.png)
A0到A4的圖框只要一個圖紙模板就搞定了?
![A0到A4的圖框只要一個圖紙<b class='flag-5'>模板</b>就搞定了?](https://file1.elecfans.com//web1/M00/F4/D5/wKgZoWcy19eAF0ZLAABXGSxO4uM322.png)
摩爾線程開源高性能線性代數模板庫MUTLASS
手寫圖像模板匹配算法在OpenCV中的實現
![手寫圖像<b class='flag-5'>模板</b>匹配算法在OpenCV中的實現](https://file1.elecfans.com/web1/M00/F4/B4/wKgZoWcxaGqAPU4YAAAPQhF4fVs669.png)
X電容和Y電容的基本概念
卷積神經網絡的基本概念、原理及特點
卷積神經網絡的基本概念和工作原理
d類放大器和ab類區別在哪
CW32F003E4芯片入門學習:4.工程模板創建(使用例程或模板)
![CW32F003E4芯片入門學習:4.工程<b class='flag-5'>模板</b>創建(使用例程或<b class='flag-5'>模板</b>)](https://file1.elecfans.com/web2/M00/C5/E1/wKgZomYDeIuAHSLzAABPS9RmuM4659.jpg)
評論