关闭

深入浅出理解:函数模板与类模板、存在的实际意义以及使用方法,

标签: 类模板C++函数模板实例
976人阅读 评论(0) 收藏 举报
分类:

在讲模板之前,先闲扯一下吧:C++最重要的特性之一就是,代码的重用,为了实现代码重用,代码就必须具有通用性

通用代码不受数据类型的影响,并且可以自动适应数据类型的变化,这种程序设计类型称为参数化程序设计

模板是C++支持参数化程序设计的工具,通过它可以实现参数化多态性。

所谓参数化多态性是指:将程序所处理的对象的类型参数化,使得一段程序可以处理多种不同类型的对象。

简单的理解,模板就是为了让代码的通用性更强。有了以上的理解, 下面理解函数模板和类模板就轻松多了。

(2)函数模板

  要讲函数模板,就得先讲一讲函数重载,相信大家都知道,函数重载通常是对于不同的数据类型完成类似的操作。

在很多时候,一个算法其实是可以处理多种数据类型的。但是用函数实现算法时,即使设计为重载函数也只是

使用相同的函数名,函数体仍然要分别定义。下面举一个求绝对值的函数重载的实例,方便大家理解。

int abs(int x)

{

return x<0?-x:x;

}

double abs(double x)

{

return x<0?-x:x;

}

可以看出,这两个函数的功能和函数体是一模一样的,但是为了实现对不同数据类型的数据求绝对值操作,我们不得不写两个

同名函数来实现操作,如果能写一段通用代码适用与多种不同数据类型该多好呢,这会使代码的可重用性大大提高,从而提高

软件的开发效率。所以聪明的人们便设计出了这么一个工具,那就是函数模板,程序员只需对函数模板编写一次,然后基于调

用函数时提供的参数类型,C++编译器将自动产生相应的函数来正确处理该类型的数据。

函数模板的定义形式如下:

template<模板参数列表>

类型名  函数名(参数列表)

{

函数体的定义;

}

说明:class或者typename标识符,指明可以接收一个类型参数,这些类型参数代表的是类型,可以是系统预定义的数据类型,也

可以是自定义类型。类型参数可以用来指定函数模板本身的形参类型、返回值类型,以及声明函数中的局部变量。

下面举一个求绝对值的函数模板的程序。

#include<iostream>

using namespace std;

template<typename T>

T  abs(T x)

{

return x<0?-x:x;

}

int  main()

{

int n_number=-5;

double d_number=-5.5;

cout<<abs(n_number)<<ebdl;

cout<<abs(d_number)<<endl;

return 0;

}

运行结果如下:


在main函数中两次调用abs()函数,

对于调用表达式abs(n_number)时,由于n_number为int类型,所以推导出模板中类型参数T为int;

当调用表达式abs(d_number)时,由于d_number为double类型,所以推导出模板类型参数T为double;

当类型参数的含义确定后,编译器将以函数模板作为一个样板,生成一个函数,这一过程便是传说中的函数模板实例化;

其实编译器会实例化以下两个函数:

int abs(int x)

{

return x<0?-x:x;

}

double  abs(double x)

{

return x<0?-x:x;

}

下面来一个稍微复杂一点的函数模板的例子,供各位深入理解一下函数模板的用法。

#include<iostream>

using namespace  std;

template<class T>

void outputArray(const T *array,int count)

{

for(int i=0;i<count;i++)

{

cout<<array[i]<<" ";

}

cout<<endl;

}

int main()

{

const  int  a_count=8,b_count=8,c_count=20;

int    a[a_count]={1,2,3,4,5,6,7,8};

double    b[b_count]={1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8};

char   c[c_count]="Welcome to see you!";

cout<<"数组a:"<<endl;

outputArray(a,a_count);

cout<<"数组b:"<<endl;

outputArray(b,b_count);

cout<<"数组c:"<<endl;

outputArray(c,c_count);

return 0;

}

运行效果如下图:



(3)类模板

类模板可以使用户为类定义一种模式,使得类中的某些数据成员、成员函数、返回值或者局部

变量能取任意类型。(包括系统预定义和用户自定义的)

如果说类是对一组对象公共性质的抽象,而类模板则是对不同类的公共性质的抽象,所以说类模板是更高层次的抽象。

类模板声明的语法形式:

template<模板参数表>

class  类名

{

类成员声明;

}

其中类成员的声明方法与普通类的声明方法其实是一模一样的,只是它的各个成员(数据成员和函数成员)通常要用到模板的类型参数T;

注意:如果要在类模板以外定义成员函数,要采用以下形式

template <模板参数表>

类型名  类名<模板参数标识符列表>::函数名(参数表)

一个类模板声明,它自身并不是一个类,它说明类的一个家族,只有当它被其它代码引用时,模板才根据需要生成具体的类。

使用一个模板类来建立对象时,格式如下:

模板名<模板参数表>对象名1,....对象名N;

下面举个例子,方便大家理解,

本例中,声明一个实现任意类型数据存取的类模板Store,然后通过具体数据类型参数对类模板进行实例化,

生成类,然后类再被实例化,

生成对象s1,s2,s3,d.

源程序如下:

#include<iostream>
#include<cstdlib>
using namespace  std;

struct Student
{
	int id;
	float gpa;
};
template<class T>
class Store
{
	private:
		T item;
		bool haveValue;
	public:
		Store();
		T& getElem();
		void putElem(const T &x);			
};
template<class T>
Store<T>::Store():haveValue(false){}

template<class T>
T& Store<T>::getElem()
{
	if(!haveValue)
	{
		cout<<"没有数据"<<endl;
		exit(1); 
	}
	return item;
}

template<class T>
void Store<T>::putElem(const T &x)
{
	haveValue=true;
	item=x;
}

int main()
{
	Store<int>  s1,s2;
	s1.putElem(3);
	s2.putElem(-7);
	cout<<s1.getElem()<<"  "<<s2.getElem()<<endl;

	Student g={101011,99};
	Store<Student>s3;
	s3.putElem(g);
	cout<<"The student ID is:  "<<s3.getElem().id<<endl;
	
	Store<double>d;
	cout<<d.getElem()<<endl;
		
	return 0;
}
运行结果:



1
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

模板——函数模板与类模板

模板(template)是一个将数据类型参数化的工具。模板分为函数模板和类模板两种。 在定义模板的时候不说明某些函数参数或者数据成员的类型,而将它们的数据类型作为模板参数。在使用模板时根据实参的...
  • welcome_xu
  • welcome_xu
  • 2012-05-10 20:06
  • 4615

模板类与类模板、函数模板与模板函数等的区别

在C++中有好几个这样的术语,但是我们很多时候用的并不正确,几乎是互相替换混淆使用。下面我想彻底辨清几个术语,这样就可以避免很多概念上的混淆和使用上的错误。 这几个词是: 函数指针——指针函数 数组指...
  • sunxx1986
  • sunxx1986
  • 2011-07-20 10:45
  • 15549

函数模板与类模板的区别

函数模板与类模板有什么区别?答:函数模板的实例化是由编译程序在处理函数调用时自动完成的,而类模板的实例化 必 须由程序员在程序中显式地指定。 即函数模板允许隐式调用和显式调用而类模板只能显示调用...
  • csw_100
  • csw_100
  • 2010-08-27 20:35
  • 10856

C++模板:函数模板、类模板、模板与继承

C++模板:描述             C++提供一种模板的机制来减少代码重复。比如:对于同一样函数使用不同的数据类型,int,double,char等。C++模板属于“元编程”的范畴。 ...
  • xiaoding133
  • xiaoding133
  • 2013-09-13 23:09
  • 37118

函数模板

模板从大体上,可以分为两种:函数模板和类模板。函数模板是算法库的基础,类模板是建立标准库容器和迭代器的基础。这一小节我们只介绍函数模板。 个人觉得,模板是C++对C的一个非常有力的扩充,即使我们不使...
  • thefutureisour
  • thefutureisour
  • 2012-07-17 09:01
  • 4646

模板类成员函数的定义和声明为什么要放在一个文件中

原文   http://blog.csdn.net/nyist327/article/details/38347049 “通常情况下,你会在.h文件中声明函数和类,而将...
  • jolin678
  • jolin678
  • 2015-11-24 17:38
  • 2131

c++中的虚函数、虚基类、类模板

一、虚函数 首先要明白C++为什么要引进虚函数这个机制, 虚函数就是在基类中被关键字virtual说明,并在派生类中重新定义的函数。虚函数的作用是允许在派生类中重新定义与基类同名的函数,并且可以通过...
  • zyazky
  • zyazky
  • 2016-08-15 14:17
  • 1571

类模板、函数模板以及类成员函数在类外定义情况

1函数模板的写法 函数模板的一般形式如下: Template 返回类型 函数名(形参表) {//函数定义体 } 说明: template是一个声明模板的关键字,表示声明一个...
  • wonengguwozai
  • wonengguwozai
  • 2016-08-03 21:09
  • 2933

嵌入式 ioctl函数的实际意义小论

函数名: ioctl 头文件:#include 功 能: 控制I/O设备 ,提供了一种获得设备信息和向设备发送控制参数的手段。用于向设备发控制和配置命令 ,有些命令需要控制参数,这些数据是不能用r...
  • skdkjxy
  • skdkjxy
  • 2013-12-02 14:45
  • 632

理解双绞线中直通线、交叉线的实际意义

一、什么是双绞线 LAN网络中最常见的数据传输铜介质是双绞线。铜介质优点是可以非常好的传导电信号,缺点是易受外界干扰而产生畸形和信号衰减,导致长距离传输过程中能量损失。为解决上述不足,提高数据传输稳...
  • SuperITPro
  • SuperITPro
  • 2012-10-22 10:45
  • 697
    我的简介:
    专注:C++、Qt软件开发
    Qt、C++编程交流群:
    302558294


    可以扫描下面微信,打赏我哦
    个人资料
    • 访问:726211次
    • 积分:9832
    • 等级:
    • 排名:第2071名
    • 原创:239篇
    • 转载:53篇
    • 译文:0篇
    • 评论:297条
    博客专栏
    最新评论