c++中的模板(template),是泛型程式設計的基礎。乙個模板就是乙個藍圖,用來建立類或函式的藍圖。
模板主要分為兩類:
函式模板(function template)
類模板(class template)
本文主要介紹類模板(class template)。
關於模板的全部內容,參考【c++深陷】之「模板」。
乙個例子:
template
<
typename t>
class
blob
void
push_back
(const t &t)
// 函式成員,定義在類外
t &operator
(size_type i)
;private
:// 資料成員
std::shared_ptr> data;
};
template
關鍵字不可以少,緊接模板引數列表。
在類中可以像使用其他型別一樣使用t
,我們定義了乙個data
,是指向vector
型別的shared_ptr
智慧型指標。
使用型別別名技術,我們定義了兩個型別成員,見第5節。
我們定義了乙個建構函式,兩個類內成員函式,乙個類外成員函式,定義見第2節。
至於為什麼size_type
型別別名這句話有乙個typename
,見第8節。
類內的函式成員直接定義即可,類外的按如下格式:
template
<
typename t>
blob
::blob()
:data
(std::make_shared>()
)template
<
typename t>
t &blob
::operator
(size_type i)
必須以template
開頭,後接和類模板相同的模板引數列表。
接下來進入了blob
的作用域內,可以適當的省略,見第6節。
在例項化類模板時,我們必須顯示指定模板實參,即顯示模板實參(explicit template argument)。
blob<
int> ia;
// 此時t為int型別
上面**編譯之後,編譯器重寫blob
模板,將每個t
都換成int
:
class
blob
;
注意,上述**僅僅是示例,並非每個函式成員都會被例項化,見第4節。
預設情況下,乙個類模板的成員函式只有當程式用到它時才進行例項化。如果乙個成員函式沒有被使用,則它不會被例項化。
但是c++總會給你意外或驚喜,此時我們可以記住這個特性,但也要認識到除了預設情況,很多情況模板類的成員函式都被例項化了。
型別別名技術,可以通過typedef
和using
來是我們的程式可讀性變強。
類模板也可以:
// 儲存string專用的blob
// 此時必須使用具體型別而不能是t
typedef blob strblob;
嚴格意義上來說,不可以定義blob
的typedef
,但是可以定義乙個模板的型別別名:
// twin是乙個型別別名
// 但是是乙個有模板實參的型別別名
template
<
typename t>
using twin = pair
;// typedef pairtwin
// 是不行的
// 這樣使用
twin<
int> pos;
在模板類自己的作用域內,可以省略模板引數列表,例如:
template
<
typename t>
class
blob
;
上面的賦值運算子沒有使用blob
的形式。
在類外:
template
<
typename t>
blob
&blob
::operator=(
const blob &rhs)
在遇到blob::
之後,都屬於類的作用域,都可以不新增
。
類模板也可以包含靜態成員:
template
<
typename t>
class
fooprivate
:static std::size_t ctr;
};
每個foo例項都有其自己的static成員例項,foo
和foo
互不干擾。
在類外定義靜態成員變數需要帶上類的模板引數列表:
template
<
typename t>
size_t foo
::ctr =0;
// 定義並初始化ctr
使用靜態成員函式,可以用一下兩種方式:
// 方式1
auto ct = foo<
int>
::count()
;// 方式2
foo<
double
> df;
ct = df.
count()
;
類的成員一共有5項:
型別成員
資料成員
函式成員
靜態成員:靜態成員變數、靜態成員函式
成員模板(函式)
其中型別成員和靜態成員都屬於類本身,通過作用域運算子::
訪問。
當我們定義了乙個類模板,有模板引數t
。假設t是乙個類型別,我們是可以訪問t
中的型別成員和靜態成員,此時我們無法區分開訪問的是哪乙個。比如:
// 是t中的靜態變數s 乘 p
// 還是t中的型別成員定義了乙個指標p
t::s * p;
c++預設訪問的是靜態資料,如果寫成上面,就執行乘法。
可以通過typename
關鍵字顯示指定我訪問的是型別:
typename t::s *p =
nullptr
;
此處的typename
和模板引數列表中的typename功能不同,注意區分。
這也是為什麼前例中blob
的size_type
有乙個typename
。
template
<
typename t>
class
blob
;
學會定義類模板、在類外定義類模板的成員函式,以及在類模板作用域內用到類模板名時可以適當省略。
在例項化類模板的時候,必須要指定模板實參。
可以使用型別別名技術,簡化我們的定義。
使用typename
來區分類模板的靜態成員和型別成員。
c 模板之類模板
函式木板比較簡單,就是把函式涉及到的型別都暫時寫成乙個t,然後呼叫的時候,給出具體的引數型別,這時候就會例項化出乙個新的函式,類模板意思差不多,就是把類裡面涉及到的型別暫時寫成乙個t,然後就可以例項化的時候傳遞乙個型別,不過類模板,要顯示的傳遞型別 include using namespace s...
C 深陷 之「函式模板」
c 中的模板 template 是泛型程式設計的基礎。乙個模板就是乙個藍圖,用來建立類或函式的藍圖。模板主要分為兩類 函式模板 function template 類模板 class template 本文主要介紹函式模板 function template 關於模板的全部內容,參考 c 深陷 之 ...
STL之類模板
筆記 b站黑馬程式設計師 template template 宣告建立模板 typename 表明其後面的符號是一種資料型別,可以用class代替 t 通用的資料型別,名稱可以替換,通常為大寫字母template class person void showperon nametype m name...