在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

{

};

从文章的讨论中,可以看到,名字是非常重要的,如果对名字的使用不恰当的话,会引起很多的麻烦和误解。我们在实际的程序中各种标识符的命名也是一门学问,为了清晰易懂,有时候还是需要付出一定的代价。

最后提醒:在本文的几个术语中,语言的重心在后面,前面的词是作为形容词使用的。

模板类与类模板、函数模板与模板函数等的区别相关推荐

  1. 模板类可以使用虚函数,模板函数不能是虚函数

    1.普通的类中怎么使用虚函数,模板类中也可以这么使用虚函数 不过需要注意的是使用模板类定义不同的类型则是两个完全不同的类. 2.模板函数不能是虚函数 编译器期望在处理类定义的时候就能确定虚函数表的大小 ...

  2. 问模板函数、函数模板,模板类、类模板的区别的问题?

    问模板函数.函数模板,模板类.类模板的区别的问题? - 赵保龙 - 博客园 问模板函数.函数模板,模板类.类模板的区别的问题? 在C++中有好几个这样的术语,但是我们很多时候用的并不正确,几乎是互相替 ...

  3. 类模板,多种类型的类模板,自定义类模板,类模板的默认类型,数组的模板实现,友元和类模板,友元函数,类模板与静态变量,类模板与普通类之间互相继承,类模板作为模板参数,类嵌套,类模板嵌套,类包装器

     1.第一个最简单的类模板案例 #include "mainwindow.h" #include <QApplication> #include <QPush ...

  4. C++ 类模板二(类模版与友元函数)

    http://www.cnblogs.com/zhanggaofeng/p/5661829.html //类模版与友元函数 #include<iostream> using namespa ...

  5. 实用经验 92 区分函数模版与模版函数,类模版和模板类

    模板就是实现代码重用机制的一种工具,它可实现类型参数化,即把类型定义为参数, 从而实现了代码的可重用性.模版可以分为两类,一个是函数模版,另外一个是类模版.在使用模板概念时,经常会遇到这4个概念:函数 ...

  6. 友元函数,友元类,类模板

    C++提供友元机制,允许外部类和函数访问类的私有成员和保护成员的辅助方法,即将它们声明为一个给定类的友元类(或友元函数),使其具有类成员函数的访问权限.但友元本身不是类的成员,它不属于任何类. 优点: ...

  7. html是一种通用的方法来,()是以一种完全通用的方法来设计函数或类而不必预先说明将被使用的每个对象的类型。A.模板B.类C....

    ()是以一种完全通用的方法来设计函数或类而不必预先说明将被使用的每个对象的类型.A.模板B.类C. 更多相关问题 394.方案设计功能下可以设置的项目不包括 (). A limitation of p ...

  8. C++模板学习02(类模板)(类模板语法、类模板与函数模板的区别、类模板中的成员函数创建时机、类模板对象做函数参数、类模板与继承、类模板成员函数类外实现、类模板分文件编写、类模板与友元)

    C++引用详情(引用的基本语法,注意事项,做函数的参数以及引用的本质,常量引用) 函数高级C++(函数的默认参数,函数的占位参数,函数重载的基本语法以及注意事项) C++类和对象-封装(属性和行为作为 ...

  9. 模板 (函数模板语法 ,类模板与函数模板的区别,:函数模板案例,普通函数与函数模板的区别,普通函数与函数模板调用规则,模板的局限性,类模板分文件编写.cpp,Person.hpp,类模板与友元)

    **01:函数模板语法: #include<iostream> using namespace std;//交换两个整型函数 void swapInt(int &a ,int &a ...

最新文章

  1. 谷歌最新发布数据集:Open Images V6 来了!新增局部叙事标注形式
  2. Kosaraju算法、Tarjan算法分析及证明--强连通分量的线性算法
  3. 一定是你想要的微服务资源springboot、springcloud、docker、dubbo
  4. 易于使用的单位和集成代码
  5. A3 没有装入任何送纸器
  6. Java面试题:final和Object类常见的方法
  7. python中列表用什么表示_python中的列表
  8. 据说学会这款数据分析工具,会被各大名企高薪哄抢
  9. uoj#422. 【集训队作业2018】小Z的礼物(MIn-Max容斥+插头dp)
  10. 简单新闻客户端APP设计
  11. QC3.0充电器快充诱骗方法,做个笔记
  12. You Only Watch Once(YOWO)
  13. oracle定时器,调用存储过程,定时从n张表中取值新增到本地一张表中
  14. 2023华东师范大学计算机考研信息汇总
  15. 人工智能界专家:现在我们的机器智商还不及老鼠
  16. 1万字!彻底看懂微信小程序
  17. 阿里云-钉钉-企业邮箱
  18. Linux常用命令——screen命令
  19. Android微信登录引起的内存泄漏
  20. [异常类] 空指针 Calendar.setTime(a) 源码剖析

热门文章

  1. ZERO助手新版更新[2008408]支持起点新站、新浪读书频道、17K、逐浪、幻剑等小说站点及百度推广
  2. 【数据库】SQL语言
  3. 医学影像学和计算机,医学影像学/计算机X线成像
  4. html5 jssdk,微信公众号与HTML 5混合模式揭秘1——如何部署JSSDK
  5. js给input控件添加onkeypress属性
  6. 远程终端 android,基于Android的远程家电控制终端设计
  7. 小米9android q测试版,小米9和MIX 3 5G安卓Q测试包发布
  8. 【案例实战】分布式应用下登录检验解决方案(JWT)
  9. 巴巴腾小腾智能对话机器人_我的“心”始终陪伴着你——巴巴腾陪护机器人“小腾”...
  10. HE4057原厂500mA线性锂离子电池充电器