1.函數指針——指針函數
函數指針的重點是指針。表示的是一個指針,它指向的是一個函數,例子:
int (*pf)();
指針函數的重點是函數。表示的是一個函數,它的傳回值是指針。例子:
int* fun();
2.數組指針——指針數組
數組指針的重點是指針。表示的是一個指針,它指向的是一個數組,例子:
int (*pa)[8];
指針數組的重點是數組。表示的是一個數組,它包含的元素是指針。例子;
int* ap[8];
3.類模闆——模闆類(class template——template class)
類模闆的重點是模闆。表示的是一個模闆,專門用于産生類的模子。例子:
使用這個vector模闆就可以産生很多的class(類),vector <int> 、vector <char> 、vector < vector <int> > 、vector <shape*> ……。
模闆類的重點是類。表示的是由一個模闆生成而來的類。
例子:
上面的vector <int> 、vector <char> 、……全是模闆類。
這兩個詞很容易混淆,我看到很多文章都将其用錯,甚至一些英文文章也是這樣。将他們區分開是很重要的,你也就可以了解為什麼在定義模闆的頭檔案.h時,模闆的成員函數實作也必須寫在頭檔案.h中,而不能像普通的類(class)那樣,class的聲明(declaration)寫在.h檔案中,class的定義(definition)寫在.cpp檔案中。請參照marshall cline的《c++ faq lite》中的[34] container classes and templates中的[34.12] why can 't i separate the definition of my templates class from it 's declaration and put it inside a .cpp file? url位址是http://www.parashift.com/c++-faq-lite/containers-and-templates.html#faq-34.12
我将幾句關鍵的段落摘錄如下,英文很好了解:
關于一個預設模闆參數的例子:
第一次我定義這個模闆并使用它的時候,是這樣用的:
array books;//我認為有預設模闆參數,這就相當于array <int> books
上面的用法是錯誤的,編譯不會通過,原因是array不是一個類。正确的用法是array <> books;
這裡array <> 就是一個用于預設模闆參數的類模闆所生成的一個具體類。
4.函數模闆——模闆函數(function template——template function)
函數模闆的重點是模闆。表示的是一個模闆,專門用來生産函數。例子:
在運用的時候,可以顯式(explicitly)生産模闆函數,fun <int> 、fun <double> 、fun <shape*> ……。
也可以在使用的過程中由編譯器進行模闆參數推導,幫你隐式(implicitly)生成。
fun(6);//隐式生成fun <int>
fun(8.9);//隐式生成fun <double>
fun(‘a’);// 隐式生成fun <char>
shape* ps = new cirlcle;
fun(ps);//隐式生成fun <shape*>
模闆函數的重點是函數。表示的是由一個模闆生成而來的函數。例子:
上面顯式(explicitly)或者隐式(implicitly)生成的fun <int> 、fun <shape*> ……都是模闆函數。
關于模闆本身,是一個非常龐大的主題,要把它講清楚,需要的不是一篇文章,而是一本書,幸運的是,這本書已經有了:david vandevoorde, nicolai m. josuttis寫的《c++ templates: the complete guide》。可惜在大陸買不到紙版,不過有一個電子版在網上流傳。
模闆本身的使用是很受限制的,一般來說,它們就隻是一個産生類和函數的模子。除此之外,運用的領域非常少了,是以不可能有什麼模闆指針存在的,即指向模闆的指針,這是因為在c++中,模闆就是一個代碼的代碼生産工具,在最終的代碼中,根本就沒有模闆本身存在,隻有模闆具現出來的具體類和具體函數的代碼存在。
但是類模闆(class template)還可以作為模闆的模闆參數(template template parameter)使用,在andrei alexandrescu的《modern c++ design》中的基于政策的設計(policy based design)中大量的用到。
類模闆注意
注意:1)類模闆不能嵌套(局部類模闆)。
2)類模闆中的靜态成員僅屬于執行個體化後的類(模闆類),不同執行個體之間不存在共享。
類模闆和函數模闆
模闆提供了代碼複用。在使用模闆時首先要執行個體化,即生成一個具體的函數或類。
函數模闆的執行個體化是隐式實作的,
即由編譯系統根據對具體模闆函數(執行個體化後的函數)的調用來進行相應的執行個體化,
而類模闆的執行個體化是顯式進行的,在建立對象時由程式指定。
如果未使用到一個模闆的某個執行個體,則編譯系統不會生成相應執行個體的代碼。
在c++中,由于子產品是分别編譯的,
如果在子產品a中要使用子產品b中定義的一個模闆的某個執行個體,而在子產品b中未使用這個執行個體,則子產品a無法使用這個執行個體,除非在子產品a中也定義了相應的模闆。
是以模闆是基于源代碼複用,而不是目标代碼複用。