zoukankan      html  css  js  c++  java
  • C++ 模板 与 泛型编程

    C++ 模板 与 泛型编程

    前言

    模板有两种:类模板和函数模板 。模板是泛型编程的基础。

    什么叫:泛型编程?

    使用独立于特定类型的方式进行编程。也就是我们在编程的时候不明确的写上类型,而是使用一个模板参数来代表某种类型。

    所以泛型编程就需要使用模板。泛型编程这种编程方法,主要使用于:容器、迭代器、算法 。比如C++著名的标准模板库中都是使用模板和泛型编程。

    并且数据结构和算法,都是大量的使用泛型编程的。所以本篇博客介绍如何使用C++进行泛型编程,来编写一个简单的队列类。下两篇博客,我们来一个实战:使用泛型编程的方法编写顺序队列 和 链式队列。


    下面,我们写一个小例子,来介绍什么是泛型编程。

    示例讲解

    现在我们来做这样的一个例子:使用泛型编程做一个队列类。

    我们先创建一个 queue.h 文件 和 一个main.cpp 文件。

    先将下面的代码复制到 queue.h 文件里面。

    #include<iostream>
    #include <iomanip>
    
    using namespace std;
    
    //template<class T>
    
    
    class Queue{
    
        struct Node{
            int a;
            Node * next;
        };
    public:
        Queue();
        ~Queue();
        void push(int b);
        void pop();
        int getlength();
        virtual void print();
    
    private:
        Node * head;
        Node * rear;
        int num;
    };
    
    void Queue::push(int b){
        Node *pl = new Node;
        pl->a = b;
        pl->next = NULL;
        rear->next = pl;
        rear = pl;
        num++;
        cout << setw(2) << b << setw(2) << " 进入队列 " << endl;
    }
    
    void Queue::pop(){
        Node *p;
        p = head->next;
        cout << "  " << setw(2) << p->a << setw(2) << " 出队 " << endl;
        head->next = p->next;
        delete p;
        num--;
    }
    
    int Queue::getlength(){
        return num;
    }
    
    void Queue::print(){
        Node *p;
        p = head->next;
        cout << "队列中的元素是:" << endl;
        while(p){
            cout << p->a << " -> ";
            p = p->next;
        }
        cout << "NULL" << endl;
    }
    
    Queue::Queue(){
        rear = head = new Node();
    }
    
    Queue::~Queue(){
        delete head;
    }
    

    接着在 main.cpp 文件里面添加下面的代码,来测试 queue.h 里面的 Queue 类。

    #include <iostream>
    #include "queue.h"
    
    using namespace std;
    
    int main(){
        Queue q;
        q.push(10);
        q.push(20);
        q.push(30);
        q.print();
    
        system("pause");
        return 0;
    }
    

    运行,输出结果:

    10 进入队列
    20 进入队列
    30 进入队列
    队列中的元素是:
    10 -> 20 -> 30 -> NULL
    请按任意键继续. . .

    因为我们在设计这个 Queue 类的时候,它只能保存整数类型(int),而且类里面的所有操作也都是对整数进行操作的。那么这个队列就只能处理整数。如果,现在我们想把小数放到队列里面,那程序编译的时候就会出错;如果现在想把字符串放到队列里面来,就更不行了。

    所以,这样编写的Queue 类就带来的一个麻烦,因为这个队列类只能处理整数类型的数据,它是一个整数队列。
    如果我们现在想要一个处理字符串的队列,很不好的方法是:再添加一个.h 文件,然后写一个处理字符串的队列类。
    世界上的数据类型很多,比如:intdoublestring、各种类、float等等。那我们岂不是要设计很多整队列类吗。
    所以这个方法是不可取的。


    应该怎么做呢?
    这个时候,就有了模板编程。

    template<class T>

    这个 T 表示一个占位符,是任何一种类型的代表。这个T 就叫做:泛型

    queue.h

    #include<iostream>
    #include <iomanip>
    
    using namespace std;
    
    
    template<class T>
    class Queue{
    
        struct Node{
            T a;
            Node * next;
        };
    public:
        Queue();
        ~Queue();
        void push(T b);
        void pop();
        int getlength();
        virtual void print();
    
    private:
        Node * head;
        Node * rear;
        int num;
    };
    
    template<class T>
    void Queue<T>::push(T b){
        Node *pl = new Node;
        pl->a = b;
        pl->next = NULL;
        rear->next = pl;
        rear = pl;
        num++;
        cout << setw(2) << b << setw(2) << " 进入队列 " << endl;
    }
    
    template<class T>
    void Queue<T>::pop(){
        Node *p;
        p = head->next;
        cout << "  " << setw(2) << p->a << setw(2) << " 出队 " << endl;
        head->next = p->next;
        delete p;
        num--;
    }
    
    template<class T>
    int Queue<T>::getlength(){
        return num;
    }
    
    template<class T>
    void Queue<T>::print(){
        Node *p;
        p = head->next;
        cout << "队列中的元素是:" << endl;
        while(p){
            cout << p->a << " -> ";
            p = p->next;
        }
        cout << "NULL" << endl;
    }
    
    template<class T>
    Queue<T>::Queue(){
        rear = head = new Node();
    }
    
    template<class T>
    Queue<T>::~Queue(){
        delete head;
    }

    main.cpp

    #include <iostream>
    #include "queue.h"
    
    using namespace std;
    
    int main(){
        Queue<int> q;
        q.push(10);
        q.push(20);
        q.push(30);
        q.print();
    
        Queue<string> qs;
        qs.push("www");
        qs.push("aobosir");
        qs.push("com");
        qs.print();
    
        qs.pop();
        qs.print();
    
        system("pause");
        return 0;
    }
    

    注意:但凡是使用到模板参数的函数,在其前面都要添加上这段代码:template<class T>

    使用 template<class T> 设计的类,就叫做类模板。

    在编程的时候,我们没有指定具体的类型;在使用的时候,我们指定具体的类型。那么这种编程方法,就叫做:泛型编程。它所用到的就是:模板

    使用这种方法来做编程的话,我只需要一个类模板,然后就可以处理任何一种类型的数据。(因为 T 就代表任何一种类型的数据。)

    总结: 如果不使用泛型编程,那么只能设计一个处理具体类型的队列类。但是我们需要各种类型的,所以学会泛型编程,对以后使用C++ 编写数据结构和算法是非常有用的。
    一个模板将所有的类型就都包括了。



    接下来的两篇博客,我们会写两个例子:
    一个是顺序队列 (里面是使用数组实现的,所以叫:顺序队列)
    一个是链式队列(里面是使用链表实现的,所以叫:链式队列)

  • 相关阅读:
    【JZOJ4616】二进制的世界
    【JZOJ4665】数列
    【JZOJ4811】排队
    2017.08.19【NOIP提高组】模拟赛B组 经济编码
    浅谈匈牙利算法
    2017.08.18【NOIP提高组】模拟赛B组 恭介的法则(rule)
    2017.08.18【NOIP提高组】模拟赛B组 沙耶的玩偶(doll)
    2017.08.15【NOIP提高组】模拟赛B组 单足跳
    2017.08.15【NOIP提高组】模拟赛B组 生日聚餐
    2017.08.12【NOIP提高组】模拟赛B组 巴比伦
  • 原文地址:https://www.cnblogs.com/aobosir/p/5928524.html
Copyright © 2011-2022 走看看