浅析C++中模板的那点事
1.什么是模板
假设现在我们完成这样的函数,给定两个数x和y求式子x^2 + y^2 + x * y的值 .考虑到x和y可能是 int , float 或者double类型,那么我们就要完成三个函数:
int fun(int x,int y);
float fun(float x,float y);
double fun(double x,double y);
并且每个fun函数内部所要完成的操作也是极其的相似。如下:
int fun(int x,int y)
{
int tmp = x *x + y * y + x * y;
return tmp;
}
float fun(float x,float y)
{
float tmp = x *x + y * y + x * y;
return tmp;
}
double fun(double x,double y)
{
double tmp = x *x + y * y + x * y;
return tmp;
}
可以看出,上面的三个函数体除了类型不一样之外,其他的完全一样,那么如果能够只写一个函数就能完成上面的三个函数的功能该多好呢?如果从这三个函数提炼出一个通用函数,而它又适用于这三种不同类型的数据,这样会使代码的重用率大大提高。实际上C++中的模板正好就是来解决这个问题的。模板可以实现类型的参数化(把类型定义为参数),从而实现了真正的代码可重用性。C++中的模板可分为函数模板和类模板,而把函数模板的具体化称为模板函数,把类模板的具体化成为模板类。下面让我们分别看看什么是函数模板和类模板吧~~~
2.模板函数
实际上我们利用函数模板,只需要一个函数就可能完成上面的三个函数了,千言万语不如看代码:
#include
using namespace std;
template
T fun(T x,T y)
{
T tmp = x *x + y * y + x * y;
return tmp;
}
int main()
{
int x1 = 1,y1 = 4;
float x2 = 1.1 , y2 = 2.2;
double x3 = 2.0 , y3 = 3.1;
cout<
}
运行结果:
如此利用模板,我们很轻而易举的达到了我们的目的,而这也大大的提高了代码的可重用性,这也让我们想起了STL中的那些算法了吧,这些算法使用多种的数据类型。实际上STL即使模板的重要应用了。
现在我们想,如果上面的代码这样调用fun(x1,y2)会怎么样呢?点击编译会出现这样的错误:
可以看到编译编译出现问题的是fun(x1,y2),说的意思就是没有对应的函数,要么x1和y2都是int型,要么x1和y2都是float型。那么我为什么要说一下这样一种情况呢?主要是为了引出模板也可以同时使用两个:
#include
using namespace std;
template
T2 fun(T1 x,T2 y)
{
T2 tmp = x *x + y * y + x * y;
return tmp;
}
int main()
{
int x1 = 1,y1 = 4;
float x2 = 1.1 , y2 = 2.2;
double x3 = 2.0 , y3 = 3.1;
cout<
}
运行结果:
当使用两个模板时,为什么fun(x1,y1)也能正确运行呢?因为当进行这个调用时,T1 = int ,T2 = int。所以这种调用也是没有问题的。
提到函数想到重载是很自然的吧,那么模板函数能不能重载呢?显然是能的了,还是看代码:
#include
using namespace std;
template
T2 fun(T1 x,T2 y)
{
cout<<"调用了两个个参数的 fun 函数 ^^ "<
return tmp;
}
template
T fun(T x , T y , T z)
{
cout<<"调用了三个参数的 fun 函数 ^^ "<
return tmp;
}
int main()
{
int x1 = 1 , y1 = 4 , z1 = 5;
float x2 = 1.1 , y2 = 2.2;
double x3 = 2.0 , y3 = 3.1;
cout<
}
运行结果:
从结果已经能看出来模版函数的重载是没有任何问题的了。那么模板函数和非模板函数之间是否能够重载呢??
#include
using namespace std;
template
T fun(T x,T y)
{
cout<<"调用了模板函数 ^^ "<
return tmp;
}
int fun(int x,int y)
{
cout<<"调用了非模板函数 ^^ "<
return tmp;
}
int main()
{
int x1 = 1 , y1 = 4;
float x2 = 1.1 , y2 = 2.2;
cout<
}
运行结果:
看以看出模版函数和非模板函数也是可能重载的,那么重载函数的调用顺序是怎么样的呢?实际上是先查找非模板函数,要有严格匹配的非模板函数,就调用非模板函数,找不到适合的非模板函数在和模板函数进行匹配。
到这里,关于模板就说这些吧~~~~
3.模板类
要是理解了模版函数,模板类就相当的简单了,只不过模版函数是对函数中的类型使用模板,而模板类是对类中的类型使用模板,这我就不多说了,下面的代码是我以前利用模板写的单链表,这个是模板的典型应用:(测试过)
#include
#include
template
struct SLNode
{
T data;
SLNode
SLNode(SLNode
{
next = nextNode;
}
SLNode(const T &item,SLNode
{
data = item;
next = nextNode;
}
};
template
class SLList
{
private:
SLNode
SLNode
SLNode
int size;
public:
SLList();
SLList(const T &item);
~SLList();
bool IsEmpty()const;
int Length()const;
bool Find(int k,T &item)const;
int Search(const T &item)const;
void InsertFromHead(const T &item);
void InsertFromTail(const T &item);
bool DeleteFromHead(T &item);
bool DeleteFromTail(T &item);
void Insert(int k,const T &item);
void Delete(int k,T &item);
void ShowListMember();
};
//构造函数
template
SLList
{
head = tail = currptr = new SLNode
size = 0;
}
//构造函数
template
SLList
{
tail = currptr = new SLNode
head = new SLNode
size = 1;
}
//析构函数
template
SLList
{
SLNode
while(!IsEmpty())
{
temp = head->next;
head->next = temp->next;
delete temp;
}
}
//判断链表是否为空
template
bool SLList
{
return head->next == NULL;
}
//返回链表的长度
template
int SLList
{
return size;
}
//查找第k个节点的阈值
template
bool SLList
{
if(k < 1)
{
cout<<"illegal position !"<
SLNode
int count = 0;
while(temp != NULL && count < k)
{
temp = temp->next;
count++;
}
if(temp == NULL)
{
cout<<"The list does not contain the K node !"<
}
item = temp->data;
return true;
}
//查找data阈值为item是表的第几个元素
template
int SLList
{
SLNode
int count = 1;
while(temp != NULL && temp->data != item)
{
temp = temp->next;
count++;
}
if(temp == NULL)
{
cout<<"The node does not exist !"<
}
else
{
return count;
}
}
//从表头插入
template
void SLList
{
if(IsEmpty())
{
head->next = new SLNode
tail = head->next;
}
else
{
head->next = new SLNode
}
size++;
}
//从表尾插入
template
void SLList
{
tail->next = new SLNode
tail = tail->next;
size++;
}
//从表头删除
template
bool SLList
{
if(IsEmpty())
{
cout<<"This is a empty list !"<
}
SLNode
head->next = temp->next;
size--;
item = temp->data;
if(temp == tail)
{
tail = head;
}
delete temp;
return true;
}
//从表尾删除
template
bool SLList
{
if(IsEmpty())
{
cout<<"This is a empty list !"<
}
SLNode
while(temp->next != tail)
{
temp = temp->next;
}
item = tail->data;
tail = temp;
tail->next=NULL;
temp = temp->next;
delete temp;
size--;
return true;
}
//在第k个节点后插入item值
template
void SLList
{
if(k < 0 || k > size)
{
cout<<"Insert position Illegal !"<
}
if(k == 0)
{
InsertFromHead(item);
return;
}
if(k == size)
{
InsertFromTail(item);
return;
}
SLNode
int count = 1;
while(count < k)
{
count++;
temp = temp->next;
}
SLNode
temp->next = new SLNode
size++;
}
//删除第k个节点的值,保存在item中
template
void SLList
{
if(k <= 0 || k > size)
{
cout<<"Ileegal delete position !"<
}
if(k == 1)
{
DeleteFromHead(item);
return;
}
if(k == size)
{
DeleteFromTail(item);
return;
}
SLNode
int count = 1;
while(count < k-1)
{
count++;
temp = temp->next;
}
SLNode
temp->next = p->next;
p->next = NULL;
item = p->data;
delete p;
size--;
}
template
void SLList
{
cout<<"List Member : ";
SLNode
while(temp != NULL)
{
cout<
temp = temp->next;
}
cout<
/*
1.引入了InsertFronHead,InsertFromTail,DeleteFromHead和DeleteFromTail用来实现Insert和Delete函数,是一个比较好的方法。
2.SLNode(T &item,SLNode
3.插入,删除分为:表头,表尾,中间插入(删除)三种情况
*/
int main()
{
int item;
SLList
list.Insert(0,11);
cout<<"list number:"<
list.Insert(2,14);
cout<<"list number:"<
list.Insert(2,13);
cout<<"list number:"<
list.Delete(2,item);
cout<<"item = "<
list.Delete(1,item);
cout<<"item = "<
list.Delete(2,item);
cout<<"item = "<
return 0;
}
利用模板的好处是,SLList中的数据可以是任意的数据类型,这也就是泛型编程的概念了吧~~~~
同类资源
- win32 dll注入程序C++源码
易语言win32dll注入程序C++源码例子源代码,如果要看效果的话需要知道目标程序是64位还是32位。...
- 最强页游中控台模板
易语言最强页游中控台模板例子源代码,编写了一个星期的页游模板历上最全,希望能对想写页游的人有所帮助。...
- 功能最全页游中控台模板
功能最全页游中控台模板例子源代码,公开的最强页游模板修复了之前发布的一些BUG。...
- http多线程注册测试模板
易语言http多线程注册测试模板例子源代码,试着用易写了个多线程注册模板,总体感觉,挺方便。...
- C++显示调用易语言编写的DLL
C++显示调用易语言编写的DLL例子源代码,最近遇到一个案子使用C++调用易编写的DLL,其中遇到调用问题,特发此贴...
- 易语言与易语言调用C++,dll测试
易语言与易语言调用C++,dll测试例子源代码,测试结果调用C++写的DLL函数比易语言快4倍,测试结果不具有专业性,...
- C++禁用及启用笔记本键盘工具
C++禁用及启用笔记本键盘工具绿色版,已经重新打包工具,可以重新下载工具了。...
- C++实现LR(1)语法分析器
C++实现LR(1)语法分析器本文件感兴趣的可以参考一下,学校老师布置的作业,编译原理实验LR(1)语法分析器。...
- 气门摇杆支座cad图,工艺卡,说明书课程设计模板
气门摇杆支座cad图,工艺卡,说明书本文件感兴趣的可以参考一下,绝对齐全,比其他的气门资源都全.内有夹具图。...
- libstdc++.so.6.10在ARM运行上的
libstdc++.so.6.10在ARM运行上的本文件感兴趣的可以参考一下,运行在ARM上的libstdc++.so.6.10。...
- 华为项目管理10大模板Excel版,可直接套用非常实用
华为项目管理10大模板Excel版,可直接套用非常实用本文件感兴趣的可以参考一下,项目组成员表、项目策划/任务...
- 面向对象编程C++和Java比较教程
面向对象编程C++和Java比较教程本文件感兴趣的可以参考一下,面向对象编程C++和Java比较教程中英文完整版pd...