C++中的模板

来源:互联网 发布:cet软件下载 编辑:程序博客网 时间:2024/05/23 00:10

  模板使我们可以用单个代码段指定一组相关函数或者一组相关类;

 

  模板包括函数模板和类模板,函数模板和类模板如同具有各种形状的模板,模板函数和模板类相当于按照模板描绘,形状相同,颜色各异;

 

  1.函数模板

     重载函数用于对于不同的数据类型执行类似的操作,函数模板用于对不同的数据类型执行相同的操作;程序员只编写一次函数模板的定义,根据调用函数时提供的参数类型,编译器会产生相应的目标代码以正确处理每种类型的调用,在C语言中,这是用预处理程序指令#define创建的宏来完成的,但是,宏无法进行类型检查,而函数模板可以消除很多类型错误,因为C++提供了安全而全面的类型检查;

 

    函数模板的定义:

     以关键字template开头,用尖括号括起来的形式类型参数表,每一个形式类型参数之前都有关键字class或者typename,

        template <class T>

        template<class T,typename ElementType>

        template<class BorderType,class FillType>

     模板定义的形式类型参数表用于指定传递给函数的参数类型,函数返回类型和声明函数中的变量,函数的定义与其他函数的定义类似,指定函数模板类型的关键字class表示"所有内部类型和用户自定义类型"

     编译器检测到程序源代码中调用模板函数时,用实际的参数类型代替整个模板定义的class,创建一个完整的函数,并编译这个新建的函数;

    尽管模板仅编写一次,但是程序中仍需实例化多个模板函数和模板类的副本,这些副本会占用大量的内存。

    模板函数与重载密切相关,通过函数模板产生的一组函数均同名,因此编译器会用重载的方法调用相应的函数;

 

2.重载模板函数

    函数模板本身可以用多种方式重载,可以提供其他函数模板,指定不同参数的相同函数名,也可以用其他非模板函数重载;

  

    如果用户使用自定义类型调用模板,模板对对象使用==,+等操作符,这些操作符需要重载;

 

    在调用函数式,编译器通过匹配过程确定调用的函数,首先,编译器寻找和使用最匹配函数名和参数类型的函数调用,如果找不到,编译器检查是否可以用函数模板产生匹配函数名和参数类型的模板函数,找到匹配的函数模板,编译器就会生成和使用相应的模板函数,但如果编译器在匹配过程中找不到函数或者函数模板,则会出现编译错误;

 

  3.类模板

    对于用户自定义的数据类型抽象出类模板,描述一个普遍意义上的堆栈,然后建立这个类的实例类(注意使用实际的数据类型代替class从而形成实例类,而不是对象),所建的类虽然是通用类的副本,但是他具有指定的类型,这样通过实例化通用类的特定版本增强软件的重用性;

   模板类通常也成为参数化类型,应为模板类需要一种或多种类型参数说明如何定制通用类的模板以形成指定的模板类(根据指定的类型形成的是类);

   如果要生成多种模板类,只需编写一个通用类模板的定义,在需要用模板建立一个新类时,只需用一种简洁的方式,让编译器写出程序需要的模板类的源代码;例如,堆栈的类模板可以作为编写各种类型堆栈的基础;

    Stack <double> doubleStack(5)

 

  上述语句中,实例化一个长度为5的对象doubleStack,该对象声明为Stack<double>类型的对象,编译器自动把模板中的参数类型T替换为double以生成double类型的Stack类的源代码,尽管程序看不到这段源代码,但仍会将其放入源代码编译;

 

  在类模板以外的成员函数均以template<class T>开头,成员函数的定义与普通成员函数的定义相似,只是Stack元素的类型要用类型参数T表示,二元作用域分辨符合Stack<T>类模板将成员函数的定义域正确的类模板范围对应起来;

 

   4.模板与继承

   类模板可以从模板类派生

   类模板可以从非模板类派生

   模板类可以从类模板派生

   非模板类可以从类模板派生

 

    5.模板与静态数据成员

    非模板类中,类的所有对象共享一个静态数据成员,静态数据成员应在文件范围内初始化;

    通过类模板实例化的每个模板类都有自己的类模板静态数据成员,该模板类的所有对象共享一个静态数据成员,和非模板类的静态数据成员一样,模板类的静态数据成员也应在文件范围内初始化,每个模板类都有自己的类模板的静态数据成员副本。

原创粉丝点击