模板类与类模板、函数模板与模板函数等的区别

来源:互联网 发布:java获取浏览器类型 编辑:程序博客网 时间:2024/06/05 04:38
在C++中有好几个这样的术语,但是我们很多时候用的并不正确,几乎是互相替换混淆使用。下面我想彻底辨清几个术语,这样就可以避免很多概念上的混淆和使用上的错误。 

这几个词是: 

函数指针——指针函数 

数组指针——指针数组 

类模板——模板类 

函数模板——模板函数 

  

1.函数指针——指针函数 

函数指针的重点是指针,指向函数的指针。表示的是一个指针,它指向的是一个函数。例子: 

int   (*pf)(); 

指针函数的重点是函数,返回指针的函数。表示的是一个函数,它返回的是一个指针。例子: 

int*   fun(); 

  

2.数组指针——指针数组 

数组指针的重点是指针,指向数组的指针。表示的是一个指针,它指向的是一个数组,例子: 

int   (*pa)[8]; 

指针数组的重点是数组,指针组成的数组。表示的是一个数组,它包含的元素是指针。例子; 

int*   ap[8]; 


  

3.类模板——模板类(class   template——template   class) 

类模板的重点是模板。表示的是一个模板,专门用于产生类的模子。例子: 

template   <typename   T> 

class   Vector 



            … 

}; 

使用这个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:   

  template <class   T> 
  class   Foo   { 
  public: 
      Foo(); 
      void   someMethod(T   x); 
  private: 
      T   x; 
  };   

Along   with   similar   definitions   for   the   member   functions:   

  template <class   T> 
  Foo <T> ::Foo() 
  { 
      ... 
  } 
  
  template <class   T> 
  void   Foo <T> ::someMethod(T   x) 
  { 
      ... 
  }   

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

  //   Bar.cpp 
  
  void   blah_blah_blah() 
  { 
      ... 
      Foo <int>   f; 
      f.someMethod(5); 
      ... 
  }   

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().   

关于一个缺省模板参数的例子: 

template   <typename  T  =  int> 

class   Array 



            … 
}; 

第一次我定义这个模板并使用它的时候,是这样用的: 

Array   books;//我认为有缺省模板参数,这就相当于Array <int>   books 

上面的用法是错误的,编译不会通过,原因是Array不是一个类。正确的用法是Array <>   books

这里Array <> 就是一个用于缺省模板参数的类模板所生成的一个具体类。 

  

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

函数模板的重点是模板。表示的是一个模板,专门用来生产函数。例子: 

template   <typename   T> 

void   fun(T   a) 



            … 



在运用的时候,可以显式(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)中大量的用到。 

template <   typename   T,   template <typename   U>   class   Y> 

class   Foo 


    … 
}; 

  
从文章的讨论中,可以看到,名字是非常重要的,如果对名字的使用不恰当的话,会引起很多的麻烦和误解。我们在实际的程序中各种标识符的命名也是一门学问,为了清晰易懂,有时候还是需要付出一定的代价。 
阅读全文
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 宅e经营贷个人没有公司怎么办 浏览器下载完插件安装不好用怎么办 要求评审专家复核他不来怎么办 微博国际版不能用微博号登录怎么办 云南省特岗登录名忘了怎么办 人行登录名忘了再怎么办 生源地贷款登录名忘了怎么办 举报19楼帖子但是不给删除怎么办 新浪微博手机号被注册了怎么办 忘记新浪微博绑定的邮箱账号怎么办 申诉找回微信账号密码失败怎么办 注册微信号时验证码错误怎么办 老板让写的报道没有当天写完怎么办 洛奇英雄传镶嵌有微章的时装怎么办 上午12点用24小时制怎么办 三分钟看懂捷信个人贷款怎么办 精神不正常的父亲到单位闹怎么办 母亲和父亲一直和我闹怎么办 儿子拿了父亲的钱买手机怎么办 电动车骑的慢的时候车头打漂怎么办 二晓啊相公太爱我了怎么办全文免费 车牌被套牌了又有违章怎么办 高中生只学好主课副科学不好怎么办 母泰迪怀孕23天了不吃饭怎么办 媳妇一再触碰我的底线怎么办 发票商品编码好多选错了分类怎么办 吃了用福尔马林泡的食物怎么办 没大没小说话不尊重人的孩子怎么办 升级安卓8.0后app闪退怎么办 业主装门占用消防通道物业怎么办? 想改名字派出所不给改怎么办 物业不给地热打压影响装修怎么办 pos机pin效码验证错误怎么办 苹果下载东西要发验证码怎么办 接口断在了丝扣里面怎么办 政府下了一张关停取缔单怎么办 微信运动数据不刷新了怎么办 邻居霸占我的土地不还我该怎么办 双层水浴式杀菌锅阀门坏了怎么办 通下水管的钢丝断水管里了怎么办 塑料水管与水阀连接处漏水怎么办