C++之模板(Template)

原创 2005年04月29日 11:27:00
模板是C++提供进行编程的一种类书工具。所以在看本文以前请先了解一下C++类书的概念及相关的知识。
1.模板的概念
模办是实现类属机制的一种工具,它的功能非常强,它是无约束类属机制和约束类属机制的集合。 它可以让用户构造模板函数。 
模板,对象, 函数之间的关系见下图:

  

2.函数模板与模板函数:

先见下例:

#include <iostream.h>

template<class T>            //模板声明

T max(T x,T y)               //定义模板
{ 
    return
(x>y)? x:y;
}

main()
{
      int i=10,j=56;
      float x1=50.34, x2=56.34;
      double y1=673.36, y2=465.972;
      cout<<"the max of i, j is:"<<max(i, j)<<"/n";
      cout<<"the max of x1, x2 is:" <<max(x1,x2)<<"/n";
      cout<<"the max of y1, y2 is:" <<max(y1,y2)<<"/n";
      return 1;
}

    上面的这个程序虽然只是实现一个很简单的比较大小的问题, 但如果不用模板, 而用我们以前的方法, 由于参数类型和返回值类型不同将需要三个函数来实现, 这样是十分麻烦的。模板成功的解决了这个问题, 程序中生成了三个模板函数, 其中max(i,j)用模板实参int将类型实参数T进行了实例化;max(x1,x1)用模板实参float将类型参数T进行了实例化;max(y1,y2)用模板实参double将类型参数T进行了实例化。

    从上面的例子我们可以看出, 函数模板提供了一类函数的抽象, 它以任意类型T为参数及函数返回值。由一个函数模板产生的函数称为模板函数, 它是函数模板的具体实例。

函数模板和模板函数的关系图:

   要提醒大家注意的一点是:虽然模板参数T可以实例化成各种类型, 但是采用模板参数T的各种参数T的各参数之间必须保持完全一致的类型。例如:

T max(T x,T y)
{
return (x>y)?x:y;
}

void func(int i, char c, float)
{
   max(i,i);   //正确
   max(c,c);   //正确
   max(c,i);   //错误
   max(f,i);   //错误
}

    解决上面的问题就需要引入一个型的概念—重载, 既可以用非模板函数重载一个同名的函数模板。 重载有两种表述方式:

    1.利用函数模板的函数体

        使用次方法是必须注意各模板参数的实参类型必须一致。例如:

        int max(int,int)

    2.重新定义函数体

        对于要重新定义函数体的重载函数, 所带参数的类型可以随意, 就象一般的重载函数一样定义。

    定义重载函数特别要注意避免产生预期的和非预期的二义性。例如:

int max(int, int);

char max(int x,char y)
{
       //......
}


   当进行函数调用时有这样一个调用形式:
msx(i,j);
   此处iint,ffloat,这个函数调用就存在着二义性。这时的调用就需要按照一定的规则安排先后顺序, 这些规则就是函数模板与同名的非模板函数的重载方法均遵循的约定:

    (1)寻找一个参数完全匹配的函数, 如果找到了就调用它。

    (2)(1)失败后, 寻找一个函数模板, 使其实例化, 产生一个匹配的模板函数, 若找到了,就调用它。

    (3)(1)(2)均失败后, 再试一试低一级的对函数的重载方法,例如通过类型转换可产生参数匹配等, 若找到了,就调用它。

    (4)(1)(2)(3)均失败, 则这是一个错误的调用。

3.类模板与模板类

    类模板与模板类的概念

    一个类模板可以让用户为类定义一种模式, 使得类中的某些数据成员,某些成员函数的参数,某些成员函数的返回值,能取任意类型。

    定义一个类模板, 一般由两方面的内容:

    (1)首先要定义类, 其格式为:

template<class T>  //声明一个模板

class name
{
    //....
}

    name为类名,在类定义体中如采用数据类型的成员, 函数参数的前面需加上T。例如:

template<class T>

class vector
{
     T * data;
     int size;
     pulic:
     vetor(int);
     T&operator[](int);
     //...
};

    (2)在类定义体外定义成员函数时, 若此成员函数中有模板参数存在, 则需在函数体外进行模板声明, 并且在函数名前的类名后缀上“<T>”.例如:

template<class T>

vector<T>::vector(int i)
{
     //....
}

template<class T>

T&vector<T>::operator[](int i)
{
     //....
}

    类模板的使用

    类模板的使用实际上是将类模板实例化成一个具体的类, 它的格式为:

    类名<实际的类型>
    例如:

main()
{
     vector<int>x(5);
     for(int i=0; i<=5;i++)
     x[i]=i;
     for(i=0;i<5;++i)
     cout<<x[i]<<"";
     cout<<"/n";
}

    类模板和模板类之间的关系, 如图:

   

    类模板使用需要注意的几点:

    (1)在每个模板定义之前, 不管是类模板还是函数模板, 都需要在前面加上模板声明:

template<class T>

    (2)类模板和结构模板在使用时, 必须在名字后面缀上模板参数<T>,如:list<T>,node<T>.

相关文章推荐

c++ template(模板)

  • 2008年01月25日 19:22
  • 2.17MB
  • 下载

C++ - 模板(template)中typename的使用方法

模板(template)中typename的使用方法 http://blog.csdn.net/caroline_wendy/article/details/23910709 声明templ...

C++基础::变量模板(variable template)

既然允许C++模板类(class template)的存在,允许C++函数模板(function template)的存在,也应当允许变量模板(variable template)的存在。 引入变量模...

C++ - 可变参数函数模板(Variadic Function Template) 详解 及 代码

可变参数函数模板(Variadic Function Template) 详解 及 代码 本文地址: http://blog.csdn.net/caroline_wendy/article/det...

C++中的类模板Template

多个类有着共同操作,但是数据类型不同。如下的3个类,getMax的功能是相同的,即求两个数中的最大值,仅仅是数据类型不同。   Cpp代码   class Compare...

[C++设计模式]template 模板方法模式

模板法模式:定义一个操作中的算法骨架,而将一些步骤延迟到子类中。 按照《headfirst 设计模式》的例子,煮茶和煮咖啡的算法框架(流程)是一样的,只是有些算法的实现是不一样的,有些是一样的。 ...

C++ - 函数模板(function template)返回值

函数模板(function template)返回值 本文地址: http://blog.csdn.net/caroline_wendy/article/details/17003679 函数...

C++模板(template)

1.模板的概念。我们已经学过重载(Overloading),对重载函数而言,C++的检查机制能通过函数参数的不同及所属类的不同。正确的调用重载函数。例如,为求两个数的最大值,我们定义MAX()函数需要...
  • dcjhyn
  • dcjhyn
  • 2017年07月19日 12:54
  • 77

C++ - 函数模板(function template) 的 推进(forward) 问题 及 解决

函数模板(function template) 的 推进(forward) 问题 及 解决 本文地址: http://blog.csdn.net/caroline_wendy/article/de...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章: C++之模板(Template)
举报原因:
原因补充:

(最多只允许输入30个字)