函数模板与类模板

函数模板,顾名思义,是在生成函数时依照的模板。函数

  有时,咱们须要对不一样的数据类型作一样的函数操做。spa

  好比:分别对一个int类型数 和 一个double类型数求平方。设计

这时,虽然都是一样的求平方操做(函数体内代码同样),可是咱们必需要编写两个不一样的函数,由于处理int类型的函数的参数和返回值类型都应该是int,而处理double类型的函数的参数和返回值都应该是double。指针

以下:函数体内操做代码同样,设计为重载函数,用相同的函数名,可是参数类型和返回值类型却都不同,函数须要定义两次。code

int Square(int a) //求int类型变量的平方值
{
  int b;b=a*a;
return b; } double Square(doublea) //求double类型变量的平方值 {
  double b;b=a*a;
return b; }

此时,若是使用函数模板就能够省去屡次重复定义函数的麻烦,消除冗余代码 ,提高代码重用性。对象

函数模板的定义形式blog

template<模板参数表>get

类型名 函数名 (参数表)编译器

{编译

  函数体定义

}

对于模板参数表:由 “class”或“typename ”加上 “类型说明符” 组成。(模板参数表还能够为“template<参数表>class” 加上 “类型说明符”,表示接收一个类模板做为参数,关于类模板的说明在后面)

模板参数表 用来指定函数模板的形参类型返回值类型以及函数中的局部变量类型

如以上Square函数的函数模板以下:

template<typename T>
T Square(T a)
{
  T b;b=a*a;
return b; }

此时,再分别计算int类型和double类型变量的平方时,咱们再也不须要手动书写两个函数,只需按以下方式执行便可。

int main()
{
    int m=2;
    double n= 3.0;
    cout<<Square(m)<<endl;
    couta<<Square(n)<<endl;
    return 0;
}

在上述Square()被调用时,编译器从实参的类型(如int)推导出函数模板的参数类型(int),而后编译器将依据函数模板来生成一个以下函数

(在调用Square(m)时,执行的函数其实是int Square(int a)这个函数,同理调用Square(n)时,实际上执行的是double Square(double a)。)

int Square(int a)
{
    int b;b=a*a;
    return b;
}

这一个过程咱们称之为,函数模板的实例化。函数模板实例化的过程用户是不用关心的。

关于函数模板有几点须要注意

1.函数模板自己在编译时不会生成任何目标代码,只有函数模板生成的实例才生成目标代码。

2.若是函数模板被多个文件引用,函数模板的函数体也应该放在头文件里,而不能只放函数模板的声明。

3.函数指针不能指向函数模板自己,只能指向函数模板的实例。

 

类模板,与函数模板相似,是生成类时依照的模板。

类模板声明语法格式

template<模板参数表>

class 类名

{

  类成员声明

}

同理,模板参数表用于影响类成员(函数成员及数据成员)的中的数据类型

例:

template<class T>
class printer{  //一个打印机类模板,能够接收并打印给定数据类型
private:
    T a;
    bool b; //用来标记是否有可给出内容
public:
    T& prin();   //给出要打印内容
    void get(const T& x);  //得到要打印内容
};

在类模板外定义其函数成员的格式以下:

template<模板参数表>

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

对应上述类模板有:

template<class T>
T& printer<T>::prin(){
    if(b)
        return a;
}
template<class T>
void printer<T>::get(const T& x){
    a=x;
    b=true;
}

类模板一样拥有实例化的过程。

使用一个类模板来创建对象方法

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

创建对象的过程:首先模板实例化生成具体的类,而后类再实例化出一个个对象

如 printer<int>p1,p2; 创建了两个能够得到并给出int类型数据的打印机p1和p2。

int main(){
    printer<int>p1,p2;
    p1.get(1);
    p2.get(2);
    cout<<"p1要打印的是"<<p1.prin()<<endl;
    cout<<"p2要打印的是"<<p2.prin()<<endl;
    return 0;
}

经过模板能够实现参数化多态性(就是将处理的对象的类型参数化,使得一段程序能够处理不一样类型的对象)。

以上。

相关文章
相关标签/搜索