三、類模板
如何實現乙個通用的加法函式呢?
int
add(
int left,
int right)
double
add(
double left,
double right)
char
add(
char left,
char right)..
....
使用函式過載雖然可以實現,但是有以下幾個不好的地方:
過載的函式僅僅只是型別不同,**的復用率比較低,只要有新型別出現時,就需要增加對應的函式
**的可維護性比較低,乙個出錯可能所有的過載均出錯
那能否告訴編譯器乙個模子,讓編譯器根據不同的型別利用該模子來生成**呢?
就好比:
如果在c++中,也能夠存在這樣乙個模具,通過給這個模具中填充不同材料(型別),來獲得不同材料的冰淇淋 (生成具體型別的**),那將會節省許多頭髮。巧的是前人早已將樹栽好,我們只需在此乘涼。
泛型程式設計:編寫與型別無關的通用**,是**復用的一種手段。模板是泛型程式設計的基礎。
函式模板代表了乙個函式家族,該函式模板與型別無關,在使用時被引數化,根據實參型別產生函式的特定 型別版本。
template
<
typename t1,
typename t2,..
....
,typename tn>
例項:
template
<
class
t>
t add
(t left, t right)
注意:typename是用來定義模板引數關鍵字,也可以使用class。
函式模板是乙個藍圖,它本身並不是函式,是編譯器用使用方式產生特定具體型別函式的模具。所以其實模板就是將本來應該我們做的重複的事情交給了編譯器。
在編譯器編譯階段,對於模板函式的使用,編譯器需要根據傳入的實參型別來推演生成對應型別的函式以供呼叫。比如:當用double型別使用函式模板時,編譯器通過對實參型別的推演,將t確定為double型別,然後產生乙份專門處理double型別的**,對於字元型別也是如此。
用不同型別的引數使用函式模板時,稱為函式模板的例項化。模板引數例項化分為:隱式例項化和顯式例項化。
a. 隱式例項化:讓編譯器根據實參推演模板引數的實際型別
template
<
typename t>
t add
(t left, t right)
//模板的例項化:也就是將函式模板引數具體化
// 函式模板呼叫原理---隱式例項化
// 編譯器在編譯階段,使用者對函式模板例項化之後,
// 編譯器會對實參型別進行推演,
// 根據推演的結果來確定模板引數列表中t的實際型別
// 根據確定的t的具體型別來生成處理具體型別的函式
// 注意:在隱式例項化中,編譯器在生成**時不會進行隱式型別轉化
intmain()
如果型別不匹配,編譯器會嘗試進行隱式型別轉換,如果無法轉換成功編譯器將會報錯。
a.乙個非模板函式可以和乙個同名的函式模板同時存在,而且該函式模板還可以被例項化為這個非模板函式
// 專門處理int的加法函式
intadd
(int left,
int right)
// 通用加法函式
template
<
class
t>
t add
(t left, t right)
void
test()
b.對於非模板函式和同名函式模板,如果其他條件都相同,在調動時會優先呼叫非模板函式而不會從該模板產生出乙個例項。如果模板可以產生乙個具有更好匹配的函式, 那麼將選擇模板。
// 專門處理int的加法函式
intadd
(int left,
int right)
// 通用加法函式
template
<
classt1,
class
t2>
t1 add
(t1 left, t2 right)
void
test()
c.模板函式不允許自動型別轉換,但普通函式可以進行自動型別轉換
template
<
classt1,
classt2,
...,
class
tn>
class 類模板名
;
實現模板型別的動態順序表:
template
<
class
t>
class
seqlist
void
pushback
(const t& data)
//尾插
_array[_size++
]= data;
}void
popback()
}bool
empty()
const
size_t size()
const
size_t capacity()
const
~seqlist()
}const t&
operator
(size_t index)
private
: t* _array;
size_t _capacity;
size_t _size;};
intmain()
; cout << array[2]
<< endl;
seqlist<
int> s1;
s1.pushback(1
);s1.
pushback(2
);s1.
pushback(3
);s1.
pushback(4
);cout << s1.
size()
<< endl;
cout << s1.
capacity()
<< endl;
return0;
}
類模板例項化與函式模板例項化不同,類模板例項化需要在類模板名字後跟<>,然後將例項化的型別放在<> 中即可,類模板名字不是真正的類,而例項化的結果才是真正的類。
// seqlist類名,seqlist才是型別
seqlist<
int> s1;
seqlist<
double
> s2;
C 中的模板(類模板 模板類 模板函式)
1 class 一般class用於定義類,在模板引入c 後,最初定義模板的方法為 template,這裡class關鍵字表明t是乙個型別 2 typename 為了避免class在這兩個地方的使用可能給人帶來混淆,所以引入了typename這個關鍵字,它的作用同class一樣表明後面的符號為乙個型別...
C 模板函式,模板類
模板如字面的意思為模具模板,並不是乙個正真的物體。例如,在編寫比較兩個數大小的 中,我們可能要比較兩個整數的大小,也能需要比較浮點數等等大小。在這些 中,基本的邏輯都是相同的,只是比較數的型別不同。此時我們就可以用模板這個概念來完成對於不同型別的引數而相同的邏輯的操作。而模板會根據實際的引數型別推演...
C 模板函式與類模板
函式模板提供了一種函式行為,該函式行為可以用多種不同的型別進行呼叫,也即是說,函式模板代表乙個函式家族。includetemplatet max t const a,t const b 無參建構函式 stack stackconst 拷貝建構函式 stack operator stackconst ...