對過載函式而言,c++的檢查機制能通過函式引數的不同及所屬類的不同。正確的呼叫過載函式。例如,為求兩個數的最大值,我們定義max()函式需要對不同的資料型別分別定義不同過載(overload)版本。
//函式1.
intmax
(int x,
int y)
;//函式2.
float
max(
float x,
float y)
//函式3.
double
max(
double x,
double y)
如果在主函式中,我們分別定義了 char a,b; 那麼在執行max(a,b);時 程式就會出錯,因為我們沒有定義char型別的過載版本。
現在,我們再重新審視上述的max()函式,它們都具有同樣的功能,即求兩個數的最大值,能否只寫一套**解決這個問題呢?這樣就會避免因過載函式定義不 全面而帶來的呼叫錯誤。為解決上述問題c++引入模板機制,模板定義:模板就是實現**重用機制的一種工具,它可以實現型別引數化,即把型別定義為引數, 從而實現了真正的**可重用性。模版可以分為兩類,乙個是函式模版,另外乙個是類模版。
函式模板的定義:一種特殊的函式,可以使用不同的型別進行呼叫,對於功能相同的函式,不需要重複編寫**,並且函式模板與普通函式看起來很類似,區別就是型別可以被引數化。
函式模板通過template與typename兩個關鍵字來定義,如下:
在使用函式模板時有兩種方式
下邊以**來體驗一下函式模板:
#include
using
namespace std;
template
<
typename t>
void
swap
(t& a, t& b)
void
main()
下邊來深入理解下函式模板:
需要注意的是:
#include
using
namespace std;
template
<
typename t1,
typename t2,
typename t3>
t1 add
(t2 a, t3 b)
intmain()
編譯執行:
在上邊的**中,我們定義了多型別引數的函式模板,呼叫時需要注意的是函式返回值需要在第乙個引數型別中顯示指定,後邊的型別可自動推導或顯示指定。
函式模板跟普通函式一樣,也可以被「過載」!
#include
using
namespace std;
template
<
typename t>
void
fun(t a)
template
<
typename t1,
typename t2>
void
fun(t1 a, t2 b)
void
fun(
int a,
float b)
intmain()
編譯輸出:
從輸出可以得到,編譯器會優先去呼叫普通函式,但是當函式模板有更好的匹配時或使用限定符<>
時,編譯器就會去匹配函式模板。
總結
小知識點:表示型別的模板引數關鍵字除了有將模板的思想應用於類,我們就可以只關注類的功能實現,不需要關注具體資料元素的型別,這種思想非常適用於編寫資料結構相關的**,比如陣列類、線性表、棧和堆等,只需要實現他們的邏輯功能,不必關注具體的資料型別。typename
還有class
,兩者通常不做區別。
c++中的類模板與函式模板一樣,都是使用template
這樣的格式來宣告使用的是類模板,像如下:
template
<
typename t>
class
test
t get()
};
這樣我們就定義了乙個簡單的類模板,其中的t代表任意的型別,可以出現在類模板中的任意地方,與函式模板不同的是,使用類模板時必須顯示的指定資料型別,編譯器無法自動推導,例如testt
;需要顯示的指定資料型別。
編譯器對類模板的處理與對函式模板的處理相同:
#include
#include
using
namespace std;
template
<
typename t>
class
test
t get()
};intmain()
我們在定義類模板時,一般的規則是:
如下,我們將上邊的test類模板實現在test.h標頭檔案中,並將成員函式在外邊實現:
#ifndef __test_h__
#define __test_h__
template
<
typename t>
class
test
t get()
;};template
<
typename t>
//類外實現的成員函式需要加上類似的模板宣告
t test
::get()
#endif
//__test_h__
與函式模板一樣,類模板也可以定義多個引數,例如:
template
<
typename t1,
typename t2>
class
test
};
總結看下面一段**:
template
<
typename t,
int n>..
.
問:這裡的n是什麼意思呢?說實話,第一次看到它,我也確實懵了…
答:用乙個int數做模板引數。
再問:也就是說在函式或者類裡面要用這個n,那為什麼不直接裡面定義它?
再答:因為要作為模板引數啊,由使用模板的人來給這個n的具體值。 比如標準庫的std::array,可以std::array,就是長度為10的陣列了。
再來看一段**也許就會更明白了:
#include
using
namespace std;
template
<
classt,
int n>
// 這裡除了含有class宣告的型別之外,還擁有乙個int型別
class
mysequence
;//類外實現的成員函式
template
<
classt,
int n>
void mysequence
::setmember
(int x, t value)
//類外實現的成員函式
template
<
classt,
int n>
t mysequence
::getmember
(int x)
intmain()
深入學習c 書單
本來有一本c 程式設計,一本c primer 沒怎麼看過 經過師兄推薦又買了effective c 和more effective c 技術面試的時候會問的比較深 要研究的比較透徹一些 第一篇一些同學問我,如何學好c 我沒有別的辦法給你們,唯一的辦法就是讀書,讀大 量的書,就可以解決。要把c 作為日...
C 深入學習 反射
目錄 一 概述 二 基本使用 2.1 獲取程式類容基本步驟 2.2 使用舉例 2.2.1 建立物件 訪問設定屬性值 使用其中無參方法 2.2.2 建立帶參建構函式並訪問其中帶參方法 2.2.3 反射過載過的方法 2.2.4 反射泛型類和泛型方法 2.2.5 反射型別中的私有類容 屬性 方法 2.2....
C 深入學習 特性
目錄 一 概述 二 基本概念 三 自定義特性 四 給物件的屬性自定義驗證規則 五 總結 特性,說的白話一點,就是說明某個東西的特殊性,它不能單獨存在,必須依附在某個東西上,這裡的東西是指c 中類,屬性,方法。特性就是對這些類,方法,屬性進一步修飾。比如說,定義個 sting 型別 屬性a 我們要求該...