函数、类模板

泛型程序设计

算法实现时不指定具体要操作的数据的类型。适用于多种数据结构。

函数模板

Template <class 类型参数1,class类型参数2,…..>

返回值类型 模板名(形参表)

{

函数体;

}

函数模板可以重载,只要它们的形参表不同即可。

C++编译器遵循以下优先顺序:

  • 先找参数完全匹配的普通函数(非由模板实例化而得的函数)
  • 再找参数完全匹配的模板函数
  • 再找实参经过自动类型转换后能匹配的普通函数
  • 上面的都不符合则报错。

可以在函数模板中使用多个类型参数,可以避免二义性。

#include <iostream>

using namespace std;

void M(int &a, int &b)
{
    cout << "M1 is called" << endl;
}

template <class T>
void M(T &a, T &b)
{
    cout << "M2 is called" << endl;
}

template <class T1, class T2>
void M(T1 &a, T2 &b)
{
    cout << "M3 is called" << endl;
}

int main()
{
    int a=0, b=0;
    double c = 0, d = 0;
    int e = 0; float f = 0;
    M(a, b);
    M(c, d);
    M(e, f);
    return 0;
}

 

运行结果:

 

 

类模板

  • 在定义类的时候给它一个/多个参数
  • 这个一个/多个参数表示不同的数据类型

调用类模板时,指定参数,由编译系统根据参数提供的数据类型自动产生相应的模板类。

类模板的定义

Template <类型参数表>

Class 类模板名

{

成员函数和成员变量

}

类型参数表的写法就是:

Class 类型参数1,class 类型参数2,….

  • 类模板里的成员函数,如在类模板外面定义时,

Template<类型参数表>

返回值类型 类模板名<类型参数名列表>::成员函数名(参数表)

{

…..

}

用类模板定义对象的写法如下:

类模板名<真实类型参数表> 对象名(构造函数实际参数表);

如果类模板有无参构造函数,那么也可以只写:

类模板名 <真实类型参数表>对象名;

使用类模板声明对象

编译器由类模板生成类的过程叫类模板的实例化

  • 编译器自动用具体的数据类型替换模板中的类型参数,生成模板类的代码
  • 由类模板实例化得到的类叫模板类。为类型参数指定的数据类型不同,得到的模板类不同。

同一个类模板的两个模板类是不兼容的

Pair<string,int> *p;

Pair<string,double> a;

p=&a//wrong;

类模板与非类型参数

类模板的参数声明中可以包括非类型参数

Template<class T, int elementsNumber >

  • 非类型参数:用来说明类模板中的属性
  • 类型参数:用来说明类模板中的属性类型,成员操作的参数类型和返回值类型。

cArray<int, 50> 和cArray<int , 40>完全是两个类,这两个类的对象之间不能互相赋值。

类模板与继承

  • 类模板派生出类模板,派生类模板的类型参数名列表中应包含基类模板的参数
  • 模板类(即类模板中类型/非类型参数实例化后的类)派生出类模板
  • 普通类派生出类模板
  • 模板类派生出普通类

类模板派生出类模板

Template <class T1, class T2>

Class A

{

T1 v1;T2 v2;

}

Template <class T1, class T2>

Class B:public A<T2, T1>

{

T1 v3;T2 v4;

}

Template<class T>

Class C:public B<T,T>

{

T v5;

}

模板类派生出类模板

Template <class T1, class T2>

Class A{T1 v1; T2 v2};

 

Template <class T>

Class B :public A<int, double>{T v};

普通类派生出类模板

Class A

{

int    m;

}

Template <class T>

Class B:public A

{

T v;

}

模板类派生出普通类

Template <class T1, class T2>

Class A{T1 v1; T2 v2};

 

Class B :public A<int ,double>

{

int v;

}

类模板实例:

#include <iostream>
#include <string>

using namespace std;

template <class T1, class T2>
class Pair
{
public:
    T1 key;
    T2 value;
    Pair(T1 key, T2 value) :key(key), value(value) {}
    bool operator <(const Pair<T1, T2> &p) const;
};
template <class T1, class T2>
bool Pair<T1,T2>::operator<(const Pair<T1, T2> &P) const
{
    return (value < P.value);
}
int main()
{
    Pair<string, int> student("Tom", 19);
    cout << student.key << " " << student.value << endl;
    return 0;
}

 

 参考链接:

https://www.coursera.org/learn/cpp-chengxu-sheji

posted @ 2016-07-09 10:33  helloforworld  阅读(351)  评论(0编辑  收藏  举报