C++中的类模板和函数模板

C++编程的时候我们通常会遇到这么一种情况就是,有时候我们需要一个数组或类来存储一组数据,但数据类型我们却无法确定,有时候可能时整型数,有可能是浮点数,也有可能是字符串。对于这种只有在程序具体运行的时候才能知道需要存储数据的类型的情况下,我们能做的就只有对每一种可能产生的类型都申请一个固定的内存,一旦需要便可以使用。但这样就造成了一个问题,如果可能产生的数据类型很多,但实际上用到的类型很少,就会产生大量的浪费。比如下面这个例子:现在我需要一个类,它能够存储我所需要的数据,存储数据的多少由开发者决定,但最多不超过20个。
在上面的例子中,很明显这个存储的类型没人知道是整型数(int),浮点数(float)还是字符(char)。这样的话,通过代码实现,就需要为各种情况都各写一个类:

#include <iostream>
#include <chrono>
#define MAXSIZE 20  //定义一个宏,表示最多能存储20个数据

using namespace std;

class IntSpace{
private:
    int maxElement;   //自定义的最大存储数
    int elementNumber;  //实际存储数
    int elementSpace[MAXSIZE]; //定义一个整形数组,用于存储所有的整形数
public:
    IntSpace(int maxEle){
        this->maxElement = maxEle;
        this->elementNumber = 0;
    }

    void addNumber(int number){
        if(this->elementNumber >= maxElement)
            cout << "Space is full!" << endl;
        else
            elementSpace[elementNumber++] = number; //存储该整型数
    }
};   //该类用于存储整型数

class CharSpace{
private:
    int maxElement;   //自定义的最大存储数
    int elementNumber;  //实际存储数
    char elementSpace[MAXSIZE]; //定义一个字符数组,用于存储所有的字符
public:
    CharSpace(int maxEle){
        this->maxElement = maxEle;
        this->elementNumber = 0;
    }

    void addNumber(char lecter){
        if(this->elementNumber >= maxElement)
            cout << "Space is full!" << endl;
        else
            elementSpace[elementNumber++] = lecter; //存储该字符
    }
};   //该类用于存储字符

int main()
{
    IntSpace* i = new IntSpace(3);
    i->addNumber(1);
    i->addNumber(2);
    i->addNumber(3);

    IntSpace* n = new IntSpace(2);
    n->addNumber(4);
    n->addNumber(5);
    return 0;
}

从以上程序可以看出来,实际上两个类CharSpace和IntSpace的结构是一模一样的,唯一的区别就在于,二者存储的类型不同。而在主程序中实际上并没有用到CharSpace这个类,在这种情况下,写一个CharSpace的类着实有点亏了。
为解决这个问题,C++提供了一个模板类的机理template,可以让需要存储的数据类型由开发者动态的决定,因此上面的函数可以使用template做修改如下:

#include <iostream>
#define MAXSIZE 20

using namespace std;

template<typename T>  //构建一个模板类
class Space{
private:
    int maxElement;
    int actualElement;
    T elementSpace[MAXSIZE];  //需要存储的类型待定,由开发者给出

public:
    Space(int maxEle) : maxElement(maxEle), actualElement(0){}

    void addElement(T element);  //定义存储函数
};

template<typename T>
void Space<T>::addElement(T element){  //具体化含有模板的存储函数
    if(this->actualElement > maxElement - 1){
        cout << "Space is full! the element " << element << " can not add into the space any more!\n" << endl;
    }
    else{
        this->elementSpace[actualElement++] = element;
    }
}

int main()
{
    Space<int> s1(3);  //分配一个Space类,其能够存储int类型的数据
    s1.addElement(1);
    s1.addElement(2);
    s1.addElement(3);
    s1.addElement(4);

    Space<char> s2(2);  //分配一个Space类,其能够存储char类型的数据
    s2.addElement('A');
    s2.addElement('B');
    s2.addElement('C');
    return 0;
}

结果如下:
在这里插入图片描述
另外,template中的模板类型也可以给定一些默认值,比如上面的例子中,如果int类型常用,那么我们则可以把T的默认值设置为int如下,这样在决定模板类型的时候就可以省略部分代码了,毕竟程序员就是能偷懒就绝不多敲码的嘛,比如以下代码:

#include <iostream>
#define MAXSIZE 20

using namespace std;

template<typename T = int>  //构建一个模板类
class Space{
private:
    int maxElement;
    int actualElement;
    T elementSpace[MAXSIZE];  //需要存储的类型待定,由开发者给出

public:
    Space(int maxEle) : maxElement(maxEle), actualElement(0){}

    void addElement(T element);  //定义存储函数
};

template<typename T>
void Space<T>::addElement(T element){  //具体化含有模板的存储函数
    if(this->actualElement > maxElement - 1){
        cout << "Space is full! the element " << element << " can not add into the space any more!\n" << endl;
    }
    else{
        this->elementSpace[actualElement++] = element;
    }
}

int main()
{
    Space<> s1(3);  //分配一个Space类,其能够存储int类型的数据,此处省略了3个字母(骄傲脸.jpg)
    s1.addElement(1);
    s1.addElement(2);
    s1.addElement(3);
    s1.addElement(4);
}

以上就是template的基本用法,template的主要应用就在STL(standard template library),比如相关的vector,list,stack,map等。

猜你喜欢

转载自blog.csdn.net/WJ_SHI/article/details/104379717