【1】模板的含义

(1) 模板就是实现代码重用的机制的一种工具,它可以实现类型参数化,即把类型定义为参数,从而实现了真正的代码可重用性。
(2) 模板可以分为两类,一个是函数模板,另外一个是类模板。

【2】什么是函数模板?

所谓函数模板,实际上就是建立一个通用的函数,其函数类型和形参类型不具体指定,用一个虚拟的类型来代替。而这个通用的类型就称为函数模板。
注:
1:凡是函数体相同的函数都可以用这个模板来代替,不必定义多个函数,只需在模板中定义一次即可
2:在调用函数时,系统会根据实参的类型来取代模板中的虚拟类型,从而实现不同类型的函数功能
定义函数模板的一般形式为
template<typename T>或
template<class T>
tempale的含义是“模板”,尖括号中先写关键字typename(或class),后面跟一个类型参数T,这个类型参数T
就是一个虚拟的类型名。它表示模板中出现的T是一个类型名,但是现在并没有指定它是哪一种具体的类型。
注:函数模板的参数可以使多个。例如
template<class T1 ,typename T2>

【3】函数模板的一个简单demo

#include<iostream>
#include<Windows.h>
using namespace std;template<typename T>      //模板声明,其中T为类型参数
T Max(T a ,T b,T c)         //定义一个通用的函数,用T作为虚拟的类型名
{if(b>a)a=b;if(c>a)a=c;return a;
}
int main()                  //主函数,控制台从这里开始运行程序
{int i1=185,i2=-76,i3=567,i;                 //定义四个整形变量double d1=56.87,d2=90.23,d3=-3214.78,d;        //定义四个双精度浮点型变量;i=Max(i1,i2,i3);                         //第一次调用函数模板,实参类型为整形;cout<<"The max is:"<<i<<endl;d=Max(d1,d2,d3);                            //第二次调用函数模板,实参类型为双精度浮点型cout<<"The max is:"<<d<<endl;system("pause");return 0;
}

【4】什么是类模板?

C++的类模板为生成通用的类声明提供了一种更好的方法,模板提供参数化类型,即能够将类型名作为参数传递给接收方来建立类或函数。
以下面的Stack类为基础来建立模板:
typedef unsigned long Item;class Stack
{
private:enum{MAX=10};Item items[MAX];int top;
public:stack();//默认的构造函数bool isempty();//判空bool isfull();//盘满bool push(const Type& item);//进栈bool top(type & item);//出栈,将栈顶元素放在item中
}

采用模板时,将使用模板定义替换Stack声明,使用模板成员函数替换Stack的成员函数,和模板函数一样,模板类以下面这样的代码开头:

template<class Type>
关键字template告诉编译器,将要定义一个模板,尖括号的内容相当于函数的参数列表,可以把关键字class看作是变量的类型名,该变量接收类型作为其值,把Type看作是该变量的名称。
这里使用class并不是代表Type的类型必须为一个类;而只是表明Type是一个通用的类型说明符,在使用模板时,将使用实际的类型替换它(指Type),较新版本的C++实现允许在这样情况下使用不太容易混淆的关键字typename代替class。
template<typename Type>
可以使用自己的泛型名代替Type,其命名规则和其它标识符相同,当前流行的选项包括T和Type,我将使用后者。当模板被调用时,Type将被具体的类型值(如int或double)取代。在模板定义中,可以使用泛型名来标识要存储在栈中的类型。对于Stack来说,这意味要将所有的typedef标识符Item替换为Type。例如,
Item item[MAX];
应改为:
Type item[Max];
同样,可以使用模板成员函数替换所有类的方法,每个函数都以相同的模板声明打头:
template <class Type>
同样应使用泛型名Type替换typedef标识符Item。另外,还需要将类限定符从Stack::改为Stack<Type>::
例如,
bool Stack::push(const Item&item)
{...
}

应改为:

template <class Type>
bool Stack<Type>::push(const Item & item)
{...
}

如果在类声明中定义了方法(内联定义),则可以省略模板的前缀和类限定符

【5】类模板的创建
下面示例程序列出了类模版 和成员函数模板
注:
不能将模版成员函数放在独立的实现文件中。由于模板不是函数,所以他们不能单独编译,模板必须与特定的模板实例化请求一起使用,为此,最简单的方法是将所有的模板信息放在一个头文件中,并在要使用这些模板的文件中包含该头文件
#ifndef STACKTP_H_
#define STACKTP_H_
template <class Type>       //类模板定义开始
class Stack
{
private:enum{MAX=10};Type items[MAX];int top;
public:Stack();//默认构造函数bool isempty();bool isfull();bool push(const Type & item);bool pop(Type & item);
};template <class Type>       //类中的成员函数模板定义开始
Stack<Type>::Stack()
{top=0;
}template<class Type>
bool Stack<Type>::isempty()
{return top==0;
}template<class Type>
bool Stack<Type>::isfull()
{return top==MAX;
}template<class Type>
bool Stack<Type>::push(const Type & item)
{if(top<MAX){items[top++]=item;return true;}else return false;
}template<class Type>
bool Stack<Type>::pop(Type &item)
{if(top>0){item=item[top--];return true;}elsereturn false;
}
#endif
【6】模板类的使用
仅在程序中包含模板并不能生成模板,而必须请求实例化,从而需要声明一个为模板类的对象,做法是:使用所需的具体类型替换泛型名,实例如下:
Stack<int> kernels; //实例化了一个用于存储int型数据的类
Stack<string> colonels; //实例化了一个用于存储String型数据的类
经上述声明,编译器将按Stack<Type>模板类声明两个独立的类声明和两组独立的类方法。类声明Stack<int>将使用int替换模板中所有的Type,而声明Stack<string>将使用String替换模板中所有的Type。
泛型标识符———— 例如这里的Type————成为类型参数,这意味着他们类似于变量,但是赋给他们的不能是数字,而必须是类型,因此在kernels声明中,类型参数Type的值为int。
注意,必须显示地提供所需类型,这与常规的函数模板是不同的,因为编译器可以根据函数的参数类型来确定要生成那种函数。

【7】函数模板的一个简单demo
#include<iostream>
#include<string>
#include<cctype>
#include"Stack.h"
using namespace std;int main()
{Stack<std::string>st;//利用模板类Stack实例化了一个空桟st,存储类型为Stringchar ch;std::string po;cout<<"Please enter A to add a purchase order,\n"<<"p to process a PO,or Q to quit.\n";while(cin>>ch&&std::toupper(ch)!='Q'){while(cin.get()!='\n'){continue;}if(!std::isalpha(ch)){cout<<'\a';continue;}switch(ch){case 'A':case 'a':cout<<"enter a PO number to add: ";cin>>po;if(st.isfull())cout<<"stack already full\n";else st.push(po);break;case 'P':case 'p':if(st.isempty())cout<<"stack already empty\n";else{st.pop(po);cout<<"PO#"<<po<<"popped\n";break;}}cout<<"Please enter A to add a purchase order,\n"<<"p to process a PO,or Q to quit.\n";}cout<<"Bey\n";return 0;
}

什么是函数模板以及什么是类模板相关推荐

  1. C++ Primer 5th笔记(chap 16 模板和泛型编程)类模板成员函数的实例化

    1. 默认情况下,一个类模板的成员函数只有当程序用到它时才进行实例化. (即使某种类型不能完全符合模板操作的要求(参见9.2节,第294页),我们仍然能用该类型实例化类todo). eg. //实例化 ...

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

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

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

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

  4. C++知识点57——类模板(2、类模板的局部特化与默认模板实参)

    接上一篇文章https://blog.csdn.net/Master_Cui/article/details/111824064 四.类模板的局部特化 类模板可以被局部特化(只指定部分模板参数而不指定 ...

  5. 【无标题】类模板详解\n类模板的定义及实例化\ntemplate\u003Cclass 模板参数>\nclass 类名 {\n // 类定义\n};\n\ntemplate\u003Ctypen

    类模板详解\n类模板的定义及实例化\ntemplate\u003Cclass 模板参数>\nclass 类名 {\n    // 类定义\n};\n\ntemplate\u003Ctypenam ...

  6. C++模板笔记十:类模板案例:通用数组类

    案例描述: 实现一个通用的数组类,要求如下: 可以对内置数据类型以及自定义数据类型的数据进行存储. 将数组中的数据存储到堆区 构造函数中可以传入数组的容量 提供对应的拷贝构造函数以及operator= ...

  7. 类模板详解\n类模板的定义及实例化 模板参数

    类模板详解\n类模板的定义及实例化\ntemplate\u003Cclass 模板参数>\nclass 类名 {\n    // 类定义\n};\n\ntemplate\u003Ctypenam ...

  8. C++ Primer 5th笔记(chap 16 模板和泛型编程) 类模板的成员函数

    1. 分类 1.1 定义在类模板内的成员函数 被隐式声明为内联函数. 1.2. 类模板外部的成员函数, 类模板的成员函数本身是一个普通函数.但是,类模板的每个实例都有其自己版本的成员函数.因此,类模板 ...

  9. c++模板--2(模板机制,模板的局限性,类模板,类模板做函数的参数)

    函数模板机制结论 编译器并不是把函数模板处理成能狗处理任何类型的函数 函数模板通过具体类型产生不同的函数 编译器会对函数模板进行两次编译,在声明的地方对模板代码的本身进行编译,在调用的地方对参数替换后 ...

最新文章

  1. Python到底是什么样的语言? Python和Java比谁更快? TensorFlow的主体是用Python写的吗?
  2. sql语句中 时间数值转换为时间格式函数
  3. 如何配置jenkins 与代理服务器吗?
  4. 短视频技术详解:Android端的短视频开发技术
  5. C语言学习之输入4个整数,要求按由小到大的顺序输出。
  6. mysql安装使用--2 用户管理
  7. C语言多项式乘法模拟,急!!!!c语言:求n次多项式的加法和乘法
  8. python职位应该叫什么_从事什么职位的人适合学习Python​?
  9. 动态修改css 规则
  10. SpringBoot之idea打包以及启动jar包
  11. SQL Server 2012完全备份、差异备份、事务日志备份和还原操作
  12. Deskpins—窗口置顶软件
  13. cookie的工作原理
  14. rgb转hsv (Verilog)
  15. VSCode 使用code runner
  16. 学习心得《稻盛和夫经营学》的读后感2300字
  17. ipv6dns服务器后面为空,ipv6获取不到网关和dns服务器
  18. 《理想藏书》书籍推荐
  19. GPS导航(4):SIM908模块
  20. [Nikon D80]月季

热门文章

  1. Java多个注解合并_Java注解合并,注解继承
  2. do sb suggest to_suggest sb to do还是doing
  3. iphone最新款手机_从甲骨到iphone,那些掉进中国式陷阱的歪果仁
  4. oracle数据库通过SQL profile 绑定SQL最优执行计划(个人实践)
  5. html怎么隐藏y方向内容,如何隐藏scroll-Y纵向滚动条,并不影响内容滚动的方法...
  6. 3种java实现多线程_实现java多线程的3种方式,99%人没用过第3种
  7. phantomjs php 登录,PHANTOMJS PHP:空响应对象
  8. java封装数组_Java封装数组之动态数组实现方法详解
  9. Eclipse/STS 在线安装阿里java代码规约插件
  10. Win10 中将网页转换成pdf的简便方法