C++学习:模板编程
- 函数模板
- 类模板
简介:
众所周知,C++这门语言是集面向过程,面向对象,以及泛型编程于一体的,之前讲了面向过程,面向对象,在这里,简单讲讲泛型编程.
泛型:也就是无类型,也就是可以容纳支持的所有类型.类似java中的ArrayList集合类一样,在创建的时候去声明类型,就可以对该类型的对象进行集中的管理操作.泛型编程的出现是为了是解决过多冗余的代码而生,想想如果做一个算法的函数,要支持所有类型的,在没有泛型之前可能要将所有类型都需要重新写一遍,那么如果通过泛型编程的话,这个时候就可以大大的降低我们的代码量.
泛型编程是独立于特定类型的方式的编写代码
而模板用于表达逻辑结构相同,但是具体元素类型不同的数据对象的通用行为
这也就是泛型编程的好处,在底层代码中,泛型的应用是十分广泛的
模板是泛型编程的基础;
通过模板可以快速的建立具有类型安全的类库集合和函数集合,使用模板可以操作不同的数据类型,从而避免需要为每一个数据类型产生一个特定的类或者函数
提示:
博主:章飞_906285288
博客地址;http://blog.csdn.net/qq_29924041
函数模板
在之前的文章中,应该有过关于泛型的简单介绍,在这里做个统筹汇总,在C++中叫函数模板,在java中也就直接叫泛型编程.
所谓函数模板:实际上是建立一个通用函数,它所用到的数据的类型(包括返回值类型、形参类型、局部变量类型)可以不具体指定,而是用一个虚拟的类型来代替(实际上是用一个标识符来占位),等发生函数调用时再根据传入的实参来逆推出真正的类型。这个通用函数就称为函数模板(Function Template)。
函数模板的定义类型:
注意:
返回值类型,形式参数类型,局部变量类型都可以用虚拟类型来代替
定义函数模板的一般形式为:
template < typename T>
返回值类型 函数名 (参数表) {
}
或者:
template < class T>
返回值类型 函数名 (参数表) {
}
如一下函数所示:
#include<iostream>
using namespace::std;
namespace zzf{
//定义加减乘除的泛型函数模板,这个时候就不需要判断类型了,对于对象的话,如果这个对象对这些运算符进行重载过的话,
//同样是支持这些运算的
//template <typename T>
template <class T>
T add(T a,T b){
return a + b;
}
template <typename T>
T del(T a,T b){
return a - b;
}
template <class T>
T mul(T a,T b){
return a * b;
}
template <class T>
T div(T a,T b){
return a / b;
}
}
using namespace::zzf;
int main(int argc,char* argv[]){
float ret_1 = add(,);
int ret_2 = add(,);
cout<<"ret_1:" << ret_1<<endl;
cout<<"ret_2:" << ret_2<<endl;
return ;
}
在上述的代码中,采用的就是无类型的泛型函数模板形式.
类模板
类模板使用户可以为类定义一种模式,使得类中的某些数据成员、某些成员函数的参数、某些成员函数的返回值能取任意类型,它跟函数模板类似
类模板是对一批成员数据类型不同的类的抽象,程序员只要为这一批类所组成的整个类家族创建一个类模板,给出一套程序代码,就可以用来生成多种具体的类
类模板就是将要处理的对象的类型参数化,是程序能够处理不同的对象(数据类型)
类模板的定义
templete <模板参数表> //参数表可以是多个
class 类名{
//类成员声明
};
//在类模板以外定义其成员
templete <模板参数表>
类型名 类名<模板参数表> ::函数名(参数表){
}
对上面的函数进行简单封装
/*
* ===========================================================================
*
* Filename: caculatorTemplate.h
* Description:
* Version:
* Created: 年月日 时分秒
* Revision: none
* Compiler: gcc
* Author: (),
* Company:
*
* ===========================================================================
*/
#ifndef __CACULATORTEMPLATE_H__
#define __CACULATORTEMPLATE_H__
template <class T>
class Caculator{
public:
Caculator(){
}
T add(T a,T b){
return a + b;
}
T del(T a,T b){
return a - b;
}
T mul(T a,T b){
return a * b;
}
T div(T a,T b){
return a / b;
}
~Caculator(){
}
private:
};
#endif
测试代码
/*
* ===========================================================================
*
* Filename: caculatorTemplateTest.cpp
* Description:
* Version: 1.0
* Created: 2017年06月25日 22时31分22秒
* Revision: none
* Compiler: gcc
* Author: (),
* Company:
*
* ===========================================================================
*/
#include<iostream>
#include"caculatorTemplate.h"
using namespace::std;
int main(int argc,char* argv[]){
//创建类的实例,注意,这个是需要指定类型T的,生成类的模板
Caculator<int> cacultor;
cout<<cacultor.add(,)<<endl;
return ;
}
注意
1:在创建类的模板时候,是需要去指定具体的类型的
2:类模板和模板类的区别:
类模板是模板的定义,不是一个实实在在的类,定义中使用的参数是通用类型参数
模板类是实实在在的类,是类模板的实例化.类中的参数被实际类型所代替
类模板是模板,模板类是类,模板是使用.类是定义
案例代码:打造属于自己的堆栈管理的模板类
/*
* ===========================================================================
*
* Filename: stack.h
* Description:
* Version: 1.0
* Created: 2017年06月26日 21时48分06秒
* Revision: none
* Compiler: gcc
* Author: (),
* Company:
*
* ===========================================================================
*/
#ifndef __STACK_H__
#define __STACK_H__
namespace zzf{
#include<iostream>
using namespace::std;
template <class T>
class Stack{
public:
Stack():top_pointer(){
array[top_pointer] = ;
}
void push(const T& t);
T pop();
T getIndexType(int index);
private:
//C++中一般使用的是枚举类型来定义常量
enum {ssize = };
T array[ssize];
int top_pointer;
};
/* *
*模板类必须将定义在头文件中
* */
template <class T>
void Stack<T>::push(const T &t){
if(top_pointer < ){
cout << "error top_pointer"<<endl;
}else{
if(top_pointer < ssize){
array[top_pointer] = t;
top_pointer++;
}
}
}
template <class T>
T Stack<T>::pop(){
if(top_pointer < ){
return array[];
}else{
return array[--top_pointer];
}
}
template<class T>
T Stack<T>::getIndexType(int index){
if(index < ) {
cout<<"error index"<<endl;
return array[];
} else {
if(index > top_pointer){
cout<<"error index"<<endl;
return array[];
}else{
return array[index];
}
}
}
}
#endif
/*
* ===========================================================================
*
* Filename: stackTest.cpp
* Description:
* Version: 1.0
* Created: 2017年06月26日 21时59分50秒
* Revision: none
* Compiler: gcc
* Author: (),
* Company:
*
* ===========================================================================
*/
#include<iostream>
#include"stack.h"
using namespace::std;
using namespace::zzf;
int main(int argc,char* argv[]){
Stack<int> stack;
stack.push();
stack.push();
stack.push();
stack.push();
stack.push();
stack.push();
stack.push();
cout<<stack.pop()<<endl;
cout<<stack.getIndexType()<<endl;
return ;
}
注意:
在模板类中,函数的声明和定义都需要在头文件中进行,否则会出现未定义的引用的错误