函数模板与类模板

函数模板

函数模板的概念

为了提高效率,实现代码复用,C++提供了一种处理机制,即使用函数模板。
定义函数模板的格式

template <模板参数表>
返回类型名 函数模板名(参数表)
{
  函数体的定义
}

函数模板的定义以关键字template开头,该关键字之后是使用尖括号<>括起来的”模板参数表“。

函数模板中函数体的定义方式与定义普通函数时类似。

函数模板的示例

程序9-1 定义求绝对值的函数模板并进行不同的调用

#include 
using namespace std;
template 

T abs(T x)
{
    return x<0?-x:x;
}

int main()
{
    int n = -5;
    int m = 10;
    double d = -5;
    float f = 3.2;
    cout<

函数指针只能指向模板的实例,而不能指向模板本身。

程序9-2 定义对象交换的函数模板

#include 
using namespace std;

template 
void Swap(T &x,T &y)
{
    T tmp = x;
    x = y;
    y = tmp;
}

class myDate
{
    public:
        myDate();
        myDate(int,int,int);
        void printDate() const;
    private:
        int year,month,day;
};

myDate::myDate()
{
    year = 1970;
    month = 1;
    day = 1;
}

myDate::myDate(int y,int m,int d)
{
    year = y;
    month = m;
    day = d;
}

void myDate::printDate()const
{
    cout<

显式实例化函数模板的格式

模板名 <实际类型参数1,实际类型参数2,...>

例如,程序9-2主函数中可以写成

Swap(n,m);
Swap(d1,d2);

函数模板可以带多个类型参数。

template 
void print(T1 arg1,T2 arg2)
{
  cout<

例9-1 定义对象比较的函数模板

template 
int myCompare(const T& left,const T& right)
{
  if(left

程序9-3 对象排序程序

#include 
using namespace std;

template 
int myCompare(const T& left,const T& right)
{
  if(left
void Swap(T &x,T &y)
{
    T tmp = x;
    x = y;
    y = tmp;
}

int main()
{
    string arraystring[10] = {"shang","xia","zuo","you","qian","hou","dong","xi","nan","bei"};
    int j;
    string temp;
    for(int i=1;i<10;i++)
    {
        j = i;
        while(j>0&&myCompare(arraystring[j-1],arraystring[j])>0)
        {
            Swap(arraystring[j],arraystring[j-1]);
            j--;
        }
    }
    for(int i = 0;i<10;i++)
        cout<

函数或函数模板调用语句的匹配顺序

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

程序9-4 重载函数模板

#include 
using namespace std;

class myDate
{
    public:
        myDate();
        myDate(int,int,int);
        friend ostream & operator<<(ostream & os,const myDate & c); //友元,插入 
    private:
        int year,month,day;
};

myDate::myDate()
{
    year = 1970;
    month = 1;
    day = 1;
}

myDate::myDate(int y,int m,int d)
{
    year = y;
    month = m;
    day = d;
}

ostream & operator<<(ostream & os,const myDate & c)
{
    os<
void print(T1 arg1,T2 arg2)
{
    cout<
void print(T arg1,T arg2)
{
    cout<

程序9-5 函数调用匹配顺序

#include 
using namespace std;
template 
T Max(T a,T b)
{
    cout<<"Template Max 1"<
T Max(T a,T2 b)
{
    cout<<"Template Max 2"<

类模板

当需要编写多个形式和功能都相似的类时,可以使用类模板机制。

类是对一组对象的公共性质的抽象,而类模板则是对不同类的公共性质的抽象,因此类模板是属于更高层次的抽象。

通过类模板,可以实例化一个个的类。

声明类模板的格式

template <模板参数表>
class 类模板名
{
   类体定义 
}

如果需要在类模板以外定义其成员函数,则需要采用以下格式

template <模板参数表>
返回类型名 类模板名<模板参数标识符列表>::成员函数名(参数表)
{
  函数体
}

当使用类模板创建对象时,要随类模板名给出对应于类型形参或普通形参的具体实参,格式

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

或

类模板名 <模板参数表> 对象名1(构造函数实参),...,对象名n(构造函数实参);

编译器由类模板生成类的过程称为类模板的实例化。由类模板实例化得到的类称为模板类。

类模板示例

程序9-6 类模板

#include 
#include 
using namespace std;

template 
class Pair
{
    public:
        T1 first;
        T2 second;
        Pair(T1 k,T2 v):first(k),second(v){}
        bool operator<(const Pair& p)const;
};

template 
bool Pair::operator<(const Pair & p) const    //Pair的成员函数operator<
{
    return first student1("Tom",19);
    Pairstudent2("Jim",21);
    Paircoordinate(10,20);
    Pairdic("word","单词");
    cout<<"学生1:"<

程序9-7 类模板

#include 
using namespace std;
template 

class TestClass
{
    public:
        T buffer[10];       //T类型的数据成员buffer数组大小固定为10
        T getData(int j);   //获取T类型buffer(数组)的第j个分量 
};

template 
T TestClass::getData(int j)
{
    return *(buffer+j);
}

int main()
{
    TestClass ClassInstA;
    int i;
    char cArr[6] = "abcde";
    for(i=0;i<5;i++)
        ClassInstA.buffer[i] = cArr[i];
    for(i = 0;i<5;i++)
    {
        char res = ClassInstA.getData(i);
        cout< ClassInstF;
    double fArr[6] = {12.1,23.2,34.3,45.4,56.5,67.6};
    for(i=0;i<6;i++)
        ClassInstF.buffer[i]=fArr[i]-10;
    for(i=0;i<6;i++)
    {
        double res = ClassInstF.getData(i);
        cout<

程序9-8 在类模板中使用函数模板

#include 
#include 
using namespace std;
template 
class Pair
{
    public:
        T1 first;
        T2 second;
        Pair(T1 k,T2 v):first(k),second(v){}
        bool operator<(const Pair& p)const;
        template 
        void print(T x)
        {
            cout<
bool Pair::operator<(const Pair & p) const    //Pair的成员函数operator<
{
    return first student1("Tom",19);
    Pairstudent2("Jim",21);
    Paircoordinate(10,20);
    Pairdic("word","单词");
    cout<<"学生1:"<(student1.first);
    coordinate.print(coordinate.first);
    return 0;
}

学生1:Tom 19
学生2:Jim 21
坐标: 10 20
字典项: word 单词
Tom位于Jim之后
Tom
10

程序9-9 类模板中使用静态成员

#include 
using namespace std;
template 
class Test
{
    public:
        Test(T num)
        {
            k += num;
        }
        Test()
        {
            k += 1;
        }
        static void incrementK()
        {
            k += 1;
        }
        static T k;
};

template 
T Test::k = 0;

int main()
{
//  static Field;
    Test a;
    Testb(4);
    cout<<"Test::\tk="<::\tk="<::k< v;
    Test m;
    cout<<"Test::\tk="<::k<::\tk="<::k<::incrementK();
    cout<<"调用Test::incrementK() Test::k="<::k<::incrementK();
    cout<<"调用Test::incrementK() Test::k="<::k<::     k=1
Test::  k=4
Test::     k=2
Test::  k=5

调用Test::incrementK() Test::k=3
调用Test::incrementK() Test::k=6

程序9-10 使用普通参数的类模板

#include 
using namespace std;
template 
class TestClass
{
    public:
        int buffer[i];
        int getData(int j);
};

template 
int TestClass::getData(int j)
{
    return *(buffer+j);
};

int main()
{
    TestClass<6> ClassInstF;
    int i;
    double fArr[6]={12.1,23.2,34.3,45.4,56.5,67.6};
    for(i=0;i<6;i++)
        ClassInstF.buffer[i] = fArr[i]-10;
        for(i=0;i<6;i++)
        {
            double res = ClassInstF.getData(i);
            cout<

类模板与继承

类模板和类模板之间、类模板和类之间可以互相继承,他们之间的常见派生关系有:

  • 普通类继承模板类。
  • 类模板继承普通类。
  • 类模板继承类模板。
  • 类模板继承模板类。

程序9-11 普通类继承模板类

#include 
using namespace std;
template
class TBase     //类模板,基类 
{
    T data;
    public:
        void print()
        {
            cout<     //从模板类继承,普通类 
{
};

int main()
{
    Derived d;
    d.print();
}

0

程序9-12 类模板继承普通类

#include 
using namespace std;
class TBase     //基类,普通类 
{
    int k;
    public:
        void print()
        {
            cout<<"TBase::"<
class TDerived:public TBase     //派生类,类模板 
{
    T data;
    public:
        void setData(T x)
        {
            data = x;
        }
        void print()
        {
            TBase::print();
            cout<<"TDerived::"< d;
    d.setData("2019");
    d.print();
}

TBase::1
TDerived::2019

程序9-13 类模板继承类模板

#include 
using namespace std;

template
class TBase     //类模板 
{
     T data1;
     public:
        void print()
        {
            cout<<"TBase::"<
class TDerived:public TBase     //派生类,类模板 
{
    T2 data2;
    public:
        void print()
        {
            TBase::print();
            cout<<"TDerived::"< d;
    d.print();
    TDerived d2;
    d2.print();
}

TBase::0
TDerived::0
TBase::
TDerived::

程序9-14 类模板继承模板类

#include 
using namespace std;

template
class TBase
{
    T data1;
    public:
        void print()
        {
            cout<<"TBase::"<
class TDerived:public TBase
{
    T2 data2;
    public:
        void print()
        {
            TBase::print();
            cout<<"TDerived::"< d;
    d.print();
    TDerivedd2;
    d2.print();
}

TBase::0
TDerived::0
TBase::1
TDerived::

你可能感兴趣的:(函数模板与类模板)