模板類與類模板、函數模板與模板函數等的區別

  在C++中有好幾個這樣的術語,可是咱們不少時候用的並不正確,幾乎是互相替換混淆使用。下面我想完全辨清幾個術語,這樣就能夠避免不少概念上的混淆和使用上的錯誤。這幾個詞是:  html

  • 函數指針——指針函數
  • 數組指針——指針數組
  • 類模板——模板類
  • 函數模板——模板函數

  最終在使用中,咱們就可讓它們實至名歸,名正言順。  

1.函數指針——指針函數  c++

  函數指針的重點是指針。表示的是一個指針,它指向的是一個函數,例子:數組

  int   (*pf)();  ide

  指針函數的重點是函數。表示的是一個函數,它的返回值是指針。例子:  函數

  int*   fun();  

2.數組指針——指針數組  

  數組指針的重點是指針。表示的是一個指針,它指向的是一個數組,例子:  工具

  int   (*pa)[8];  ui

  指針數組的重點是數組。表示的是一個數組,它包含的元素是指針。例子;  this

  int*   ap[8];  

3.類模板——模板類(class   template——template   class)  spa

  類模板的重點是模板。表示的是一個模板,專門用於產生類的模子。例子:  設計

1 template <typename T>
2 class Vector
3 {
4     ...
5 };

  使用這個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  

  我將幾句關鍵的段落摘錄以下,英文很好理解:  

  In order for the compiler to generate the code, it must see both the  template definition (not just declaration) and the specific types/whatever used to "fill in" the template. For example, if you're trying to use a  Foo<int>, the compiler must see both the Foo template and the fact that  you're trying to make a specific Foo<int>. 

  Suppose you have a template Foo defined like this: 

1 template<class   T>
2 class   Foo {
3 public:
4     Foo();
5     void   someMethod(T   x);
6 private:
7     T   x;
8 };

  Along with similar definitions for the member functions:   

 1 template<class   T>
 2 Foo<T>::Foo()
 3 {
 4     ...
 5 }
 6 
 7 template<class   T>
 8 void   Foo<T>::someMethod(T   x)
 9 {
10     ...
11 }

  Now suppose you have some code in file Bar.cpp that uses Foo<int>:  

  //   Bar.cpp  

1 void   blah_blah_blah()  
2 {  
3   ...  
4   Foo<int>   f;  
5   f.someMethod(5);  
6   ...  
7 }    

  Clearly somebody somewhere is going to have to use the "pattern" for the  constructor definition and for the someMethod() definition and instantiate those when T is actually int. But if you had put the definition of the  constructor and someMethod() into file Foo.cpp, the compiler would see the  template code when it compiled Foo.cpp and it would see Foo<int> when it  compiled Bar.cpp, but there would never be a time when it saw both the  template code and Foo<int>. So by rule above, it could never generate the code for Foo<int>::someMethod().  

  關於一個缺省模板參數的例子:  

1 template   <typename   T = int>
2 class   Array
3 {
4   ...
5 };

  第一次我定義這個模板並使用它的時候,是這樣用的:  

  Array   books;//我認爲有缺省模板參數,這就至關於Array<int>   books  

  上面的用法是錯誤的,編譯不會經過,緣由是Array不是一個類。正確的用法是Array<>   books;  

  這裏Array<>就是一個用於缺省模板參數的類模板所生成的一個具體類。  

4.函數模板——模板函數(function   template——template   function)  

  函數模板的重點是模板。表示的是一個模板,專門用來生產函數。例子:  

1 template   <typename   T>  
2 void   fun(T   a)  
3 {  
4   ...
5 }  

  在運用的時候,能夠顯式(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 template<   typename   T,   template<typename   U>   class   Y>  
2 class   Foo  
3 {  
4   ...
5 };   

  從文章的討論中,能夠看到,名字是很是重要的,若是對名字的使用不恰當的話,會引發不少的麻煩和誤解。咱們在實際的程序中各類標識符的命名也是一門學問,爲了清晰易懂,有時候仍是須要付出必定的代價。  

  最後提醒:在本文的幾個術語中,語言的重心在後面,前面的詞是做爲形容詞使用的。

 

 

  轉自:http://blog.sina.com.cn/s/blog_8b6cb0930100xair.html

相關文章
相關標籤/搜索