C++实验三 模板

C++实验三 模板,第1张

C++实验三 模板

模板函数与模板类
    • 实验环境
    • 模板概念
      • 特化模板函数
    • 模板类
    • 队列类

实验环境

*** 作系统:win10
gcc:8.1.0
开发软件:qt5.14.2

模板概念

在C++的相关代码开发中,我们常常会遇到的是关于代码通用性的问题;模板就是C++支持参数化程序设计的工具,通过它可以实现参数化多态性。这里可以看一下两个例子。

int sum(int x,int y)
{
	return x+y;
}
double sum(double x,double y)
{
	return x+y;
}

事实上两个函数除了数据类型以外进行的功能是一样的,但如果像这样分开写其实大大的降低了代码整体的通用性,对于设计和使用都是不方便的选择。这就是模板需要起作用的地方,模板的定义如下

template<模板参数表>
类型名 函数名(参数表)
{
	函数
}

为了方便理解,以上述的例子为出发点进行衍生。

#include
using namespace std;
template
test sum(test a,test b)
{
	return a+b;
}
int main()
{
	int test1=1,test2=2;
	double test3=3,test4=4;
	cout< 


可以看到,这样的方式成功完成了对一般模板函数的成功运用。

特化模板函数

但此时需要考虑一个特殊状况,使用模板时会遇到一些特殊的类型需要特殊处理,不能直接使用当前的模板函数,所以此时我们就需要对该类型特化出一个模板函数,如下所示。

template
bool Isequal(test &t1, test &t2)
{
	return t1 == t2;
}

上述的函数可以判断传入的两个参数是否相等,但显而易见的,当数据类型为字符型时,上述函数无法生效,故在此使用特化的模板函数。

template<>
bool Isequal(char*& t1, char*& t2)
{
	return strcmp(t1, t2) == 0;
}

上面展示的就是特化的模板函数,需要注意几点

  • 使用模板特化时,必须要先有基础的模板函数(就是上面第一个模板函数)
  • template 后直接跟<> 里面不用写类型
  • 函数名<特化类型>(特化类型 参数1, 特化类型 参数2 , …) 在函数名后跟<>其中写要特化的类型
  • 特化的函数的函数名,参数列表要和原基础的模板函数相同
    同样 我们简单的运行来验证结果。

    从上图可以看到,运行的结果符合预期,特化的函数成功运作了。
模板类

既然存在模板函数的概念,同样也存在模板类的概念。使用类模板的过程可以使得程序员为类定义一种模式,使得类中的部分数据成员,部分成员函数的参数,返回值和局部变量能取不同的类型。这里为了方便说明,简单的建立一个**队列(queue)**的类来进行实践。

首先让我们对简单的模板类进行说明。

template 
class Complex{
    
public:
    //构造函数
    Complex(T a, T b)
    {
        this->a = a;
        this->b = b;
    }
    
    //运算符重载
    Complex operator+(Complex &c)
    {
        Complex tmp(this->a+c.a, this->b+c.b);
        return tmp;
    }
        
private:
    T a;
    T b;
}

int main()
{
    //对象的定义,必须声明模板类型,因为要分配内容
    Complex a(10,20);  
    Complex b(20,30);
    Complex c = a + b;
    
    return 0;
}

其中简单的展示了类模板的使用方式,重要的部分都有进行注释。

队列类

话不多说,先把实现的代码放在下面

#include 
using namespace  std;
template
struct Node {
    T data;
    Node *next;
};

template
class MyQueue {
public:
    MyQueue(); // 构造函数
    ~MyQueue(); // 析构函数
    void Push(const T& x); // 压入队列
    T Front(); // 获取队头元素
    T Back(); // 获取队尾元素
    void Pop(); // 删除队头元素
    bool Empty() const; // 判断队列是否为空
    int Size() const; // 返回队列的大小
private:
    Node *head; // 头指针
    Node *tail; // 尾指针
};

// 构造函数
template
MyQueue::MyQueue() {
    head = tail = NULL;
}

// 析构函数
template
MyQueue::~MyQueue() {
    Node *current;

    while(head != NULL) {
        current = head;
        head = head->next;
        delete current;
        current = NULL;
    }
}

// 压入队列
template
void MyQueue::Push(const T &x) {
    Node *current;

    current = new Node();
    if(current == NULL) {
        std::cerr << "申请空间失败!n";
        exit(1);
    }
    current->data = x;
    current->next = NULL;
    if(head == NULL)
        head = current;
    else
        tail->next = current;
    tail = current;
}

// 获取队头元素
template
T MyQueue::Front() {
    Node *current;
    if(head == NULL) {
        std::cout << "队列为空!n";
        exit(1);
    }
    current = head;
    return current->data;
}

// 获取队尾元素
template
T MyQueue::Back() {
    Node *current;
    if(head == NULL) {
        std::cout << "队列为空!n";
        exit(1);
    }
    current = tail;
    return tail->data;
}

// 删除队头元素
template
void MyQueue::Pop() {
    if(head == NULL) {
        std::cout << "队列为空!n";
        exit(1);
    }
    head = head->next;
}

// 判断队列是否为空
template
bool MyQueue::Empty() const {
    if(head == NULL)
        return true;
    return false;
}

// 返回队列的大小
template
int MyQueue::Size() const {
    int n;
    Node *current;

    n = 0;
    current = head;
    while(current != NULL) {
        n++;
        current = current->next;
    }
    return n;
}

可以看到,上面的类在使用了模板类的前提下实现了队列的简单的构造函数,析构函数,向队列中加入元素,删除队列元素,返回队列长度,获取队头和队尾的长度等的基本 *** 作。
先让我们看一下实现的效果

与模板类的实现在上述的队列代码中都有体现,以下任然需要补充一些在使用类模板时会遇到的问题。

  • 模板类本身未指定所使用的数据类型,不能单独编译模板类的实现。 只用在使用模板类的阶段,指定了模板中的数据类型,编译器才能正常编译。因此,在实际开发中,必须把实现全部写在头文件里面,把声明和实现分开的做法不可取。
  • 模版不支持在局部函数中声明定义或使用
  • 自动类型推导,必须推导出一致的数据类型T,才可以使用模板必须要确定出T的数据类型,才可以使用。
  • 模版类的定义和实现不能分开写在不同文件中,否则会导致编译错误

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5503107.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-12
下一篇 2022-12-13

发表评论

登录后才能评论

评论列表(0条)

保存