通常int sum(int a, int b)這裡的兩個形參變數a b,就是為了接受實參的值。而模板的意義就在於此,模板就是針對型別的,使型別也可以進行引數化,即由原來的的固定的轉化為可變的。
模板的意義:對型別也可以進行引數化了
「{}」裡面的內容不進行編譯,型別不知道
1、定義乙個模板形參列表 :
template< typename t>;
2、定義乙個通用的的模板;
bool
compare
(t a, t b)
//compare是乙個函式模板,compare+模板型別<>=函式
可以用typename/class;也可以定義多個模板引數,用逗號隔開
模板非型別引數
//函式模板
template
<
typename t>
//定義乙個模板引數列表
//用t型別 定義具體的形參變數
bool
compare
(t a, t b)
//compare是乙個函式模板,compare+模板型別<> = 函式
=》根據使用者傳入的實參型別,推出模板型別引數的具體型別
模板的例項化:在函式的呼叫點進行模板的例項化
模板函式:根據給定的型別(compare(12, 24);)或推導出的型別(compare(15, 35);),得到的實際的函式叫,模板函式,從而進行編譯
/*
在函式呼叫點,編譯器用使用者指定的函式型別,從原來的模板例項化乙份函式**出來
//模板函式
bool compare(int a, int b)
bool compare(double a,duoble b)
*/int
main()
以下是函式模板的源**:
//函式模板
template
<
typename t>
//定義乙個模板引數列表
//用t型別 定義具體的形參變數
bool
compare
(t a, t b)
//compare是乙個函式模板,compare+模板型別<> = 函式
//針對compare函式模板,提供const char* 型別的特例化版本
template
<
>
bool compare<
const
char
*>
(const
char
* a,
const
char
* b)
//非模板函式 -》普通函式
bool
compare
(const
char
* a,
const
char
* b)
/*在函式呼叫點,編譯器用使用者指定的函式型別,從原來的模板例項化乙份函式**出來
//模板函式
bool compare(int a, int b)
bool compare(double a,duoble b)
bool compare(const char* a,const char* b)
*/int
main()
模板函式、模板的特例化、非模板函式的「 過載 」』關係?它們的函式名都不同,所以不是過載函式。
注意:
模板不能在乙個.cpp檔案中定義,在另乙個.cpp檔案使用
模板呼叫之前,一定要看到模板定義的地方,這樣的話,模板才能夠進行正常的例項化,產生能被編譯器編譯的**。所以,模板**都是放在標頭檔案中,然後在原始檔當中直接進行#include包含
函式模板是用來定義型別引數的,那麼函式模板還可以定義非型別引數嗎?可以的,這個正好可以解決我們經常遇到的一類問題:
類模板的使用實際上是類模板例項化成乙個具體的類(而非模板類)。
模板引數列表裡面一般都是定義引數,用來初始化型別的。即都是定義模板型別引數。模板型別引數:< > 裡面可以由typename/class定義 模板 型別引數t (可以定義多個,由逗號隔開)t用來接收型別的。
模板的非型別引數都是常量,只能使用不能修改。例如 size。在模板引數列表裡面定義非型別引數用來接收非型別引數。
而且這個常量只能且必須是整數型別(整型的:int char long short。位址也是整型的:其他型別的指標或者引用也是可以的)。
template
<
typename t,
int size>
模板型別引數t 和 模板非型別引數
下面我將通過編寫乙個棧來描述類模板,通常情況下,我們編寫的棧只能針對一開始就定義好的型別,而類模板就只需要編寫一次棧,在任何需要使用棧的地方,訪問任意型別的元素都是可以通過相應型別去例項化它即可。
template
<
typename t>
class
seqstack
//模板名稱 + 型別引數列表 = 類名稱
裡是賦值,初始化的效率比賦值的高
~seqstack()
seqstack
(const seqstack
&stack)
:_top
(stack._top)
,_size
(stack._size)
} seqstack
&operator=(
const seqstack
&stack)
return
*this;}
void
push
(const t &val)
void
pop(
) t top()
const
bool
full()
const
bool
empty()
const
private
: t *_pstack;
//為了定義乙個記憶體可增長的棧,所以定義乙個指標
int _top;
//棧頂的下標肯定是整型
int _size;
//大小肯定是整型
void
expand()
delete
_pstack;
_pstack = ptmp;
_size =
2* _size;}}
;int
main()
在類外實現成員方法:
1 需要在類體內 宣告
2 前面需要加類的作用域,但現在seqstack不是類(而是模板名稱)。
模板名稱+ < t > 才是類名稱 如下:
//再需要型別引數t的時候,只能去重新定義這個 型別引數t
template
<
typename t>
void seqstack
::push
(const t& val)
// 入棧操作
現在用整型例項化了乙個 棧。在用整型例項化這個類模板的時候,編譯階段就會用類模板來例項化乙份 專門處理整型的 類出來。
int
main()
如上:因為 我們在這裡只是定義了乙個物件,只用到建構函式;return 0; 那用到了析構函式。所以編譯器在用類模板來例項化乙份 專門處理整型的 模板類出來的時候,裡面只有建構函式和析構函式,沒有其他方法(因為沒用到)。只有在用到這些方法的時候,才會加上這些方法。
這是類模板的選擇性例項化:用某乙個型別去例項化類模板得到乙個模板類的時候,這個模板類裡面有多少成員方法?編譯器主要看的是在**裡面使用到哪些方法然後才在例項化的過程中給到模板類(沒有呼叫到的方法 就不產生)減少編譯器的工作。
類模板還可以加 預設的型別引數:template
使用的時候就可以:seqstack<> s2; (型別引數有預設值)
C 模板函式,模板類
模板如字面的意思為模具模板,並不是乙個正真的物體。例如,在編寫比較兩個數大小的 中,我們可能要比較兩個整數的大小,也能需要比較浮點數等等大小。在這些 中,基本的邏輯都是相同的,只是比較數的型別不同。此時我們就可以用模板這個概念來完成對於不同型別的引數而相同的邏輯的操作。而模板會根據實際的引數型別推演...
模板 函式模板 類模板
模板主要是針對資料型別,不同的資料型別卻具有相同的操作形式,比如說,同樣是做入棧,int和double由於資料型別不一樣,需要做兩個棧才能滿足需求,誠然可以使用函式過載,但是終歸棧的操作是一樣的,只是資料型別不一樣。所以在此基礎上,假設,我們首先將所有的資料型別視為乙個大類,將它引數化,等到要用的時...
C 加密模板(類模板 函式模板)
題目描述加密機制包括明文 密文 金鑰。用金鑰對明文進行加密後就得到密文。在古典加密機制中,偏離值是一種常見的方法,加密過程為 1 在已知資料中找出最大值 2 用最大值減去各個數值,得到相應的偏離值 3 偏離值加上金鑰就得到密文 例如明文為1 2 3 4 5,金鑰是10,加密過程為 1 找出明文的最大...