07C++类模板 函数模板与模板函数

合集下载

C++Template基础篇(一):函数模板详解

C++Template基础篇(一):函数模板详解

C++Template基础篇(⼀):函数模板详解Template所代表的泛型编程是C++语⾔中的重要的组成部分,我将通过⼏篇blog对这半年以来的学习做⼀个系统的总结,本⽂是基础篇的第⼀部分。

为什么要有泛型编程C++是⼀门强类型语⾔,所以⽆法做到像动态语⾔(python javascript)那样⼦,编写⼀段通⽤的逻辑,可以把任意类型的变量传进去处理。

泛型编程弥补了这个缺点,通过把通⽤逻辑设计为模板,摆脱了类型的限制,提供了继承机制以外的另⼀种抽象机制,极⼤地提升了代码的可重⽤性。

注意:模板定义本⾝不参与编译,⽽是编译器根据模板的⽤户使⽤模板时提供的类型参数⽣成代码,再进⾏编译,这⼀过程被称为模板实例化。

⽤户提供不同的类型参数,就会实例化出不同的代码。

函数模板定义把处理不同类型的公共逻辑抽象成函数,就得到了函数模板。

函数模板可以声明为inline或者constexpr的,将它们放在template之后,返回值之前即可。

普通函数模板下⾯定义了⼀个名叫compare的函数模板,⽀持多种类型的通⽤⽐较逻辑。

template<typename T>int compare(const T& left, const T& right) {if (left < right) {return -1;}if (right < left) {return 1;}return 0;}compare<int>(1, 2); //使⽤模板函数成员函数模板不仅普通函数可以定义为模板,类的成员函数也可以定义为模板。

class Printer {public:template<typename T>void print(const T& t) {cout << t <<endl;}};Printer p;p.print<const char*>("abc"); //打印abc为什么成员函数模板不能是虚函数(virtual)?这是因为c++ compiler在parse⼀个类的时候就要确定vtable的⼤⼩,如果允许⼀个虚函数是模板函数,那么compiler就需要在parse这个类之前扫描所有的代码,找出这个模板成员函数的调⽤(实例化),然后才能确定vtable的⼤⼩,⽽显然这是不可⾏的,除⾮改变当前compiler的⼯作机制。

函数模板的定义及使用

函数模板的定义及使用

函数模板的定义及使用函数模板是一种通用的函数定义,可以用于不同的数据类型或不同的参数列表。

函数模板的定义可以让程序员编写通用的函数,不需要为不同的数据类型或不同的参数列表编写不同的函数。

本文将介绍函数模板的定义及使用。

一、函数模板的定义函数模板是通过在函数定义中使用模板参数来定义的。

模板参数可以是类型参数或非类型参数。

类型参数是指可以用来表示任何类型的参数,例如int、double、char等;非类型参数是指可以用来表示任何值的参数,例如整数、浮点数、指针等。

函数模板的定义方式如下:template <typename T>T max(T a, T b) {return a > b ? a : b;}上面的代码定义了一个名为max的函数模板,它有两个类型为T 的参数,并返回两个参数中的最大值。

在函数模板中,typename关键字用来定义类型参数,T是类型参数的名称。

函数模板的调用方式如下:int main() {int x = 10, y = 20;double a = 1.5, b = 2.5;std::cout << max(x, y) << std::endl; // 输出20std::cout << max(a, b) << std::endl; // 输出2.5return 0;}在上面的示例中,我们调用了max函数模板两次,一次传递了两个int类型的参数,一次传递了两个double类型的参数。

由于max 函数模板是通用的,它可以接受不同类型的参数,并返回相应类型的结果。

二、函数模板的特化有时候,我们需要为某些特定的类型或参数列表编写特定的函数实现,这时可以使用函数模板的特化。

函数模板的特化是指为特定的类型或参数列表提供特定的函数实现。

函数模板的特化方式如下:template <>bool max<bool>(bool a, bool b) {return a && b;}上面的代码定义了一个max函数模板的特化,它针对bool类型的参数,返回两个参数的逻辑与运算结果。

函数模板与类模板的区别

函数模板与类模板的区别

函数模板与类模板的区别函数模板与类模板有什么区别?答:函数模板的实例化是由编译程序在处理函数调⽤时⾃动完成的,⽽类模板的实例化必须由程序员在程序中显式地指定。

即函数模板允许隐式调⽤和显式调⽤⽽类模板只能显⽰调⽤这期间有涉及到函数模板与模板函数,类模板与模板类的概念(类似于类与类对象的区别)请看下⾯例⼦#include "stdafx.h"#include <iostream>using namespace std;//使⽤模板创建⼀个返回最⼤值的函数//这是⼀个函数模板template <class Type>Type MaxValue(Type a,Type b){if ( a > b){return a;}elsereturn b;}//创建⼀个堆栈模板类//这是⼀个类模板template <class T>class Stack{public:Stack(){ m_nPos = 0;}~Stack(){}void Push(T value);T Pop();bool IsEmpty(){return m_nPos == 0;}bool HasElement(){return !IsEmpty();}bool IsFull(){return m_nPos == STATCK_SIZE;}private:int m_nPos;//使⽤常量表⽰堆栈的⼤⼩const static int STATCK_SIZE = 100;T m_Data[STATCK_SIZE];};//模板类的成员函数实现template <class T>void Stack<T> ::Push(T value){//使⽤后置递增操作符m_Data[m_nPos++] = value;}template <class T>T Stack<T>::Pop(){//使⽤前置递减操作符return m_Data[--m_nPos];}void TestMaxValue(){//隐式调⽤//函数模板的实例化在程序调⽤时⾃动完成cout << MaxValue(100, 204)<< endl;//MaxValue(100, 204)这是⼀个模板函数cout << MaxValue(2.5002,30.003) << endl;//MaxValue(2.5002,30.003)这也是⼀个模板函数//当然由程序员⾃⼰指定也可以//显⽰调⽤cout << MaxValue<int>(10,20) << endl;cout << MaxValue<double>(2.5002,30.003) << endl;}void TestStack(){//测试模板类(整数)Stack <int> intStack;//类模板的实例化由程序员显⽰的指定intStack.Push(10);intStack.Push(20);intStack.Push(30);while (intStack.HasElement()){cout << intStack.Pop() << endl;}//测试模板类(浮点)Stack <float> floatStack;//类模板的实例化由程序员显⽰的指定floatStack.Push(1.001);floatStack.Push(2.002);floatStack.Push(3.003);while (floatStack.HasElement()){cout << floatStack.Pop() << endl;}//测试动态创建对象//Stack创建的指针必须指明类型Stack<int>* pInt = new Stack<int>();类模板的实例化由程序员显⽰的指定pInt->Push(10);pInt->Push(20);pInt->Push(30);while (pInt->HasElement()){cout << pInt->Pop() << endl;}if ( pInt != NULL){delete pInt;pInt = NULL;}}。

《高级语言程序设计(C++)》考核大纲

《高级语言程序设计(C++)》考核大纲

高级语言程序设讨(C++)课程考核大纲一、适应对象修读完本课程规定内容的光电信息科学与工程、电子科学与技术专业的本科生;提出并获准免修本课程、申请进行课程水平考核的光电信息科学与工程、电子科学与技术专业的本科生;提出并获准副修第二专业、申请进行课程水平考核的非光电信息科学与工程、非电子科学与技术专业的本科生。

二' 考核目的考核学生分析问题的方法和基本问题的解决能力,掌握C++语言的基本内容及程序设计的基本方法与编程技巧情况,以及C++高级语言的实际操作和应用等综合能力。

三' 考核形式与方法基于本课程应用性、工程实践性强的特点,考核方式将结合平时作业、上机实验、期末工程设计的各个环节。

使学生能够注重平时学习的过程,改变学生从应试型到能力型。

考试内容侧重于知识的综合应用。

突出平时课堂表现与实践环节,平时成绩含课堂表现、作业完成质量;实践环节含实验方案设计、实验操作、实验结果分析与报告完成质量。

四' 课程考核成绩构成考核成绩构成:平时作业(30%) +上机实验(30%) +期末工程设计(40%)五、考核内容与要求(-)理论知识考核内容及要求第1章面向对象程序设计概述考核内容:1.1面向对象程序设计的基本概念面向对象程序设计的基本特性及其优点考核要求:掌握面向对象程序设计的基本概念、基本特性。

第2章C++基础考核内容:2.1C++源程序的结构C++源程序调试的基本步骤2.2标识符基本数据类型2.3C++语句数据的简单输入和输出2.4C++中标识符的作用域C++对传统C语言的一些扩充考核要求:掌握C++源程序的结构、基础及调试的基本步骤。

第3章类与对象考核内容:3.1类和对象的定义this 指针3.2构造函数与析构函数const对象和const成员函数3.3对象数组静态成员3.4友员指向类成员的指针考核要求:掌握类和对象的定义、指针及作用。

第4章继承性考核内容:4.1继承性概述继承与派生4.2单继承多继承4.3派生类中的成员重定义支配规那么、赋值兼容规那么与二义性4.4虚基类考核要求:掌握继承性的概念及类型。

C++中类模板与模板类定义及具体使用方法

C++中类模板与模板类定义及具体使用方法

类模板类模板也称为类属类或类生成类,是为类定义的一种模式,它使类中的一些数据成员和成员函数的参数或返回值可以取任意的数据类型。

类模颁布是一个具体的类,它代表着一族类,是这一族类的统一模式。

使用类模板就是要将它实例化为具体的类。

定义类模板的一般形式为:template<class 数据类型参数标识符>class 类名{//……}其中,template是声明类模板的关键字;template后面的尖括号不能省略;数据类型参数标识符是类模板中参数化的类型名,当实例化类模板时,它将由一个具体的类型来代替。

定义类模板时,可以声明多个类型参数标识符,各标识符之间用逗号分开。

类定义中,凡要采用标准数据类型的数据成员、成员函数的参数或返回类型的前面都要加上类型标识符。

如果类中的成员函数要在类的声明之外定义,则它必须是模板函数。

其定义形式为:template<class 数据类型参数标识符>数据类型参数标识符类名<数据类型参数标识符>∷函数名(数据类型参数标识符形参1,……,数据类型参数标识符形参n){函数体}模板类将类模板的模板参数实例化后生成的具体的类,就是模板类。

由类模板生成模板类的一般形式为:类名<数据类型参数标识符>对象名1,对象名2,…,对象名n;这里的数据类型参数标识符对应的是对象实际需要的数据类型。

6.4 应用举例例6.1 函数模板的声明和模板函数的生成的例。

#include<iostream.h>template<typename T> //声明模板函数,T为数据类型参数标识符void swap(T &x, T &y) //定义模板函数{T z; //变量z可取任意数据类型及模板参数类型Tz=y;y=x;x=z;}void main(){int m=1,n=5;double a=8.9,b=3.4;cout<<”m=”<<m<<”n=“<<n<<endl;cout<<”a=”<<a<<”b=”<<b<<nedl;swap(m,n); //实例化为整型模板函数swap(a,b); //实例化为双精度型模板函数cout<<“m与a,n与b交换以后:”<<endl;cout<<”m=”<<m<<”n=“<<n<<endl;cout<<”a=”<<a<<”b=”<<b<<endl;}程序运行结果:m=1 n=5a=8.9 b=3.4m与a,n与b交换以后:m=5 n=1a=3.4 b=8.9例6.2 类模板的声明和模板类的生成的例。

类模板与模板类详解

类模板与模板类详解

类模板与模板类详解在C++的Template中很多地⽅都⽤到了typename与class这两个关键字,有时候这两者可以替换,那么这两个关键字是否完全⼀样呢? 事实上class⽤于定义类,在模板引⼊c++后,最初定义模板的⽅法为:template<class T>,这⾥class关键字表明T是⼀个类型,后来为了避免class在这两个地⽅的使⽤可能给⼈带来混淆,所以引⼊了typename这个关键字,它的作⽤同class⼀样表明后⾯的符号为⼀个类型,这样在定义模板的时候可以使⽤下⾯的⽅式了: template<typename T>.在模板定义语法中关键字class与typename的作⽤完全⼀样区分类模板与模板类的概念 ⼀个类模板(类⽣成类)允许⽤户为类定义个⼀种模式,使得类中的某些数据成员、默认成员函数的参数,某些成员函数的返回值,能够取任意类型(包括系统预定义的和⽤户⾃定义的)。

如果⼀个类中的数据成员的数据类型不能确定,或者是某个成员函数的参数或返回值的类型不能确定,就必须将此类声明为模板,它的存在不是代表⼀个具体的、实际的类,⽽是代表⼀类类。

类模板定义:定义⼀个类模板,⼀般有两⽅⾯的内容:A。

⾸先要定义⼀个类,其格式为:template<class T>class test{....}test为类名,在类定义体中,如果采⽤通⽤数据类型的成员,函数参数的前⾯需加上T,其中通⽤类型T可以作为普通成员变量的类型。

还可以作为成员函数的参数和返回类型等。

例如:1 template<class T>23 class Test4 {5 private:6 T n;7 const T i;8 public:9 Test():i(0) {}10 Test(T k);11 ~Test(){}1213 void print();14 T operator+(T x);15 };如果在类外定义成员函数,若此成员函数中有模板参数存在,则除了需要和⼀般类的类外定义成员函数⼀样的定义外,还需要在函数外进⾏模板声明例如:1 template<class T>2 void Test<T>::print()3 {4 std::cout<<"n="<<n<<std::endl;5 std::cout<<"i="<<i<<std::endl;6 }1 template<class T>2 Test<T>::Test(T k):i(k){ n=k;} //构造函数34 template<class T>5 T Test<T>::operator+(T x){6 return n + x;7 }关于类模板的使⽤:类模板的使⽤实际上是将类模板实例化成⼀个具体的类,它的格式为:类名<实际的类型>模板类是类模板实例化后的⼀个产物,说个具体点的例⼦吧,我们把类模板⽐作是⼀个做饼⼲的模⼦,⽽模板类就是⽤这个模⼦做出来的饼⼲,⾄于这个饼⼲是什么味道的就要看你⾃⼰在实例化时⽤的是什么材料了,你可以做巧克⼒饼⼲,也可以做⽜奶饼⼲,这些饼⼲出了材料不⼀样外,其它的东西都是⼀样的了。

C语言中实现模板函数

C语言中实现模板函数在C语言中,没有内置的模板函数的概念,但是可以使用宏定义来实现类似于模板函数的功能。

宏定义能够根据传入的参数自动生成相关的代码,以实现代码的复用和泛化。

下面将详细介绍如何使用宏定义来实现模板函数。

C语言中的宏定义使用`#define`关键字,可以用于定义常量、函数和代码块。

在这里,我们将使用宏定义来实现一个模板函数,以便根据参数类型自动生成相应的代码。

下面是实现一个模板函数的步骤:1. 定义宏函数:我们可以使用宏定义来创建一个通用的函数,其中参数类型用宏参数来表示。

例如,我们可以定义一个通用的`max`函数来返回两个参数中的较大值:```c#define MAX(a, b) (a > b ? a : b)```在这个例子中,`MAX`是宏函数的名称,`a`和`b`是函数的参数,`(a>b?a:b)`是返回值。

调用`MAX`函数时,编译器会自动将函数调用替换为相应的代码。

2.使用宏函数:我们可以在代码中使用`MAX`宏函数来代替原始的函数调用。

例如,我们可以调用`MAX`函数来比较两个整数的最大值:```cint a = 10;int b = 20;int max_value = MAX(a, b);```在这个例子中,`max_value`将被赋值为`20`,因为`b`的值大于`a`的值。

3.使用宏函数的限制:使用宏函数的一个重要限制是,它只能用于生成表达式,而不能用于定义局部变量或执行复杂的逻辑操作。

因此,使用宏函数时应该注意避免出现副作用或不符合预期的行为。

4.对于更复杂的模板函数:如果想要实现更复杂的模板函数,可以使用更高级的技术,如泛型编程。

泛型编程可以通过使用无类型指针和类型转换来实现对任意类型的支持。

然而,泛型编程在C语言中需要更复杂的技术和代码,超过了本文介绍的范围。

总结来说,虽然C语言中没有内置的模板函数的概念,但可以使用宏定义来实现类似的功能。

宏定义可以根据传入的参数类型来生成相应的代码,实现代码的复用和泛化。

C++之模板(Template)

C++之模板(T emplate)模板是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进行了实例化。

常用C模板范文

常用C模板范文C语言是一种非常常用的编程语言,被广泛应用于各种领域,包括嵌入式系统、操作系统、游戏开发等。

为了提高开发效率,程序员常常使用一些常用的C模板来完成重复性的编码工作。

下面是一些常用的C模板供参考:1.输入输出模板:```c#include <stdio.h>int mai//提示用户输入printf("请输入您的名字: ");//声明一个字符串变量用于存储用户的输入char name[20];//从标准输入读取用户输入的字符串scanf("%s", name);//输出用户的名字printf("您好,%s!\n", name);return 0;```2.循环模板:```c#include <stdio.h>int mai//初始化计数器int i = 0;//执行循环while (i < 10)//打印计数器的值printf("%d ", i);//更新计数器i++;}//输出换行符printf("\n");return 0;```3.条件语句模板:```c#include <stdio.h>int mai//初始化变量int number = 10;//判断变量的值是否小于等于5if (number <= 5)printf("number 小于等于 5\n");}//判断变量的值是否大于5且小于等于10else if (number > 5 && number <= 10)printf("number 大于 5 且小于等于 10\n");}//默认情况elseprintf("number 大于 10\n");}return 0;```4.函数模板:```c#include <stdio.h>//定义一个函数来计算两个整数的和int sum(int a, int b)return a + b;int mai//调用函数并输出结果printf("1 + 2 = %d\n", sum(1, 2));return 0;```5.结构体模板:```c#include <stdio.h>//定义一个学生结构体struct Studentchar name[20];int age;float score;};int mai//创建一个学生对象struct Student student1;//给学生对象赋值strcpy(, "Tom");student1.age = 18;student1.score = 95.5;//输出学生的信息printf("姓名:%s\n", );printf("年龄:%d\n", student1.age);printf("分数:%f\n", student1.score);return 0;```以上是一些常用的C模板,可以根据具体的需求进行修改和扩展。

Excel2007函数大全

Excel2007函数大全一、函数应用基础1.函数和公式(1)什么是函数Excel函数即是预先定义,执行计算、分析等处理数据任务的特殊公式。

以常用的求和函数SUM为例,它的语法是“SUM(number1,number2,......)”。

其中“SUM”称为函数名称,一个函数只有唯一的一个名称,它决定了函数的功能和用途。

函数名称后紧跟左括号,接着是用逗号分隔的称为参数的内容,最后用一个右括号表示函数结束。

参数是函数中最复杂的组成部分,它规定了函数的运算对象、顺序或结构等。

使得用户可以对某个单元格或区域进行处理,如分析存款利息、确定成绩名次、计算三角函数值等。

按照函数的来源,Excel函数可以分为内置函数和扩展函数两大类。

前者只要启动了Excel,用户就可以使用它们;而后者必须通过单击“工具→加载宏”菜单命令加载,然后才能像内置函数那样使用。

(2)什么是公式函数与公式既有区别又互相联系。

如果说前者是Excel预先定义好的特殊公式,后者就是由用户自行设计对工作表进行计算和处理的公式。

以公式“=SUM(E1:H1)*A1+26”为例,它要以等号“=”开始,其内部可以包括函数、引用、运算符和常量。

上式中的“SUM(E1:H1)”是函数,“A1”则是对单元格A1的引用(使用其中存储的数据),“26”则是常量,“*”和“+”则是算术运算符(另外还有比较运算符、文本运算符和引用运算符)。

如果函数要以公式的形式出现,它必须有两个组成部分,一个是函数名称前面的等号,另一个则是函数本身。

2.函数的参数函数右边括号中的部分称为参数,假如一个函数可以使用多个参数,那么参数与参数之间使用半角逗号进行分隔。

参数可以是常量(数字和文本)、逻辑值(例如TRUE或FALSE)、数组、错误值(例如#N/A)或单元格引用(例如E1:H1),甚至可以是另一个或几个函数等。

参数的类型和位置必须满足函数语法的要求,否则将返回错误信息。

(1)常量常量是直接输入到单元格或公式中的数字或文本,或由名称所代表的数字或文本值,例如数字“2890.56”、日期“2003-8-19”和文本“黎明”都是常量。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

几点说明: 例6.3 #include<iostream.h> template<class type1, class type2> void myfunc(type1 x,type2 y) { cout<<x<<‟‟<<y<<end1; } void main() { myfunc(10, ”hao”); myfunc(0.123, 10L); } 程序运行结果为: 10 hao 0.123 10
const int size=10 Template<class Type> class stack{ Type stck[size]; Int tos; public: void init() {tos=0;} void push(Type ch); Type pop(); }; 成员函数 push() 和 pop() 在类定义体外定义为 template<class Type> void stack<Type>::push(Type ob) { if(tos= =size) { cout<<”stack is full”; return; } stck[tos]=ob; tos++; }
13
template<class Type> Type stack<Type>::pop() { if(tos= =0) { cout<,”stack is empty”; return 0; } tos--; return stck[tos]; }
14
类模板不代表一个具体的、实际的类,而代表一类类。实际上,类 模板的使用就是将类模板实例化成一个具体的类,它的格式为: 类名<实际的类型>对象名; 例如,使用上面的类模板,创建两个模板参数为char型的对象,语句 如下: stack<char>s1,s2;
接1 例6.2
6
int int_array[]={1,2,3,4,5,6,7,8,9,10}; double double_array[]={1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9,10.10}; void main() { int itotal=sum(int_array,10); double dtotal=sum(double_array,10); cout<<”The summary of integer array are:” <<itotal<<endl; cout<<”The summary of double array are:” <<dtotal<<endl; } 程序运行结果为: The summary of integer array are:55 The summary of double array are:59.6 几点说明: ⑪在函数模板中允许使用多个类型参数。但在template定义部分的 每个模板形参前必须有关键字class。
例6.1 函数模板的程序
4
# include<iostream.h> 程序运行结果如下: # include<string.h> the max of il,i2 is :56 template<class AT> the max of fl,f2 is :24.5 AT max(AT x , AT y ) the max of dl,d2 is :4656.346 { return (x>y)? X : y; } the max of cl,c2 is :n void main() { int il=10, i2=56; float fl=12.5, f2=24.5; double b1=50.344,d2=4656.346; char c1=‟k‟,c2=‟n‟; cout<<”the max of il,i2 is: “<<max(i1,i2)<<endl; cout<<”the max of fl,f2 is: “<<max(f1,f2)<<endl; cout<<”the max of dl,d2 is: “<<max(d1,d2)<<endl; cout<<”the max of cl,c2 is: “<<max(c1,c2)<<endl; }
ห้องสมุดไป่ตู้};
template<class Type> void stack<Type>::push(Type ob) { if (tos= =size) { cout<<”stack is full”; return; } stck[tos]=ob; tos++; } template<class Type> Type stack<Type>::pop() { if (tos= =0) { cout<<”stack is empty”; return 0; } tos--; return stck[tos]; }
函数模板和模板函数的关系
5
函数模板 max(x,y)
实例化 实例化 实例化 实例化
模板函数 模板函数 模板函数 模板函数 max(i1,i2) max(f1,f2) max(d1,d2) max(c1,c2) (i1,i2为整型) (f1,f2为浮点型 (d1,d2为双精型 (c1,c2为字符型 ) ) ) 例 6.2 与指针有关的模板 #include<iostream.h> template<class T> T sum(T *array, int size=0) { T total=0; for(int i=0; i<size; i++) total+=array[i]; return total; };
11
6.3 类模板和模板类
12
一个类模板(也称为类属类或类生成类)允许用户为类定义一种模 子,使得实例化类中的某些数据成员,某些成员函数的参数或者 返回值,能取任意数据类型。 定义一个类模板,其格式如下: template<class Type> class 类名 { //… }; 关键字class (或typename)后面的Type是类型参数。在实例化类 定义中,欲采用通用数据类型的数据成员,成员函数的参数或返 回值,前面需要加上Type。 例如,下面的程序中建立了一个用来实现堆栈的类模板。
模板
2
模板分为函数模板(模子)和类模板(模子),允许用户分别用 它们构造(套印)出(模板)函数和(模板)类。 图显示了模板(函数模板和类模板),模板函数,模板类和对象 之间的关系。
模 板 (函数模板和类模板) 实例化 模板函 数 模子 实例化 模板类
实例化
对象
6.2 函数模板与模板函数
3
6.2.1 函数模板的声明与模板函数的生成 函数模板的声明格式如下: template <class 类型参数> 返回类型 函数名(模板形参表) { 函数体 } 其中template是一个声明模板的关键字,它表示声明一个模板。 例如,将求最大值函数max () 定义成函数模板,如下所示: template<class T> 或 template <typename T> T max(T x , T y) { return (x>y)? x:y; } 其中T为类型参数,它可用基本类型或用户自定义的类型。在使用 函数模板时,必须将其实例化,即用实际的数据类型替代它。
当出现调用语句 max(“abcd”,”efgh”);时,执行的是这个重载的非 模板函数。 在c++中函数模板与同名的非模板函数重载时,调用的顺序遵 循下述约定 ⑪寻找一个参数完全匹配的函数,如果找到了就调用它。 ⑫寻找一个函数模板,将其实例化,产生一个匹配的模板函数,若 找到了,就调用它。 ⑬若⑪和⑫都失败,再试一试低一级的对函数的重载方法,若找到 了,就调用它。
8
6.2.2 函数模板的异常处理
9
虽然函数模板中的模板形参T可以实例化为各种类型,但实例化T的 各模板实参之间必须保持完全一致的类型,否则会发生错误。请 看下面的例子。 Template<class T> T max(T x,T y) { return(x>y)?x:y; } void fun(int i,char c) { max(i,i); //正确,调用max(int,int) max(c,c); //正确,调用max(char,char) max(i,c); //错误 max(c,i); //错误 } 这里出现错误的原因是,如对语句 max(i,c); 编译器将先按变量i将T解释为int类型,此后出现的模板实参c不能 解释为int类型时,便发生错误。解决这个问题有以下两种方法: ⑪采用强制类型转换,如将调用语句 max(i,c); 改写成 max(i,int(c));
⑫用非模板函数重载函数模板,这种重载有两种表述方式: 10 ①只声明一个非模板函数的原型,而不给出函数体,它的函数体是 借用函数模板的函数体。当执行此重载版本时会自动调用函数模 板的函数体。 template<class T> T max(T x,T y) { return(x>y)? x:y; } int max (int,int); //非模板函数的原型 void fun(int i,char c) { max(i,i); //正确,调用max(int,int) max(c,c); //正确,调用max(char,char) max(i,c); //正确,调用max(int,int),它支持数据间的隐式转换 max(c,i); //正确,调用max(int,int),它支持数据间的隐式转换 } ②定义一个完整的非模板函数,此方法定义的重载函数,所带参数 的类型可以随意,就像一般的重载函数一样定义。例如: char *max( char *x, chen *y) { return(strcmp(x,y>0)?x:y;) }
相关文档
最新文档