c++学习:类模板+万能版链表实战

发布时间:2024年01月08日

目录

类模板

思考

解决方法 创建类模板

?实战

设计一个任意数据类型的数组模板

设计一个单向链表类模板? --万能版链表

1. 先做一个整形的链表类

2. 将整形链表类改为万能版

3. 将他放入hpp里,hpp是专门存放模板的,新建一个forwardlist.hpp,将模板移到hpp里


类模板

思考

//浮点型比较类
class CompareA{
public:
    CompareA(double a,double b);
    double max(){return x>y?x:y;}
    double min(){return x<y?x:y;}
private:
    double x,y;
};
//整数比较类
class CompareB{
public:
    CompareA(int a,int b);
    int max(){return x>y?x:y;}
    int min(){return x<y?x:y;}
private:
    int x,y;
};

如果还要比较其他不同数据的类,那需要很多个类

解决方法 创建类模板

//类模板
template<class T>
class Compare{
public:
    Compare(T a,T b);
    T max();
    T min(){return x<y?x:y;}
private:
    T x,y;
};

template<class T>
Compare<T>::Compare(T a,T b):x(a),y(b)
{

}

template<class T>   //Compare<T> 等同于类名
T Compare<T>::max()
{
    return x>y?x:y;
}

    Compare<double> mya(10.5,20.5);
    Compare<int> myb(100,200);

思考类模板能不能作为基类被继承

  • 可以被继承,继承的派生类可以是模板也可以是具体的类
//基类模板
template<class T>
class Base
{

};

//派生类 可以是 具体的类
class Child:public Base<int>
{

};

//派生类还是一个模板
template<class T,typename Tx=char,typename Ty = double>
class Child1:public Base<T>
{

};

Child1<int> mya;

?实战

设计一个任意数据类型的数组模板

#include <iostream>
using namespace std;
//动态数组模板
template<class T>
class Vector
{
public:
    Vector(int size=256)
    {
        m_size = size;
        m_ptr = new T[m_size];
    }
    ~Vector()
    {
        delete []m_ptr;
    }
    T& operator[](int index)
    {
        return m_ptr[index];
    }
    T*addr() // T*data()
    {
        return m_ptr;
    }
private:
    int m_size;
    T *m_ptr;
};
int main()
{
    //int array[10]
    Vector<int> v1(10);
    v1[0] = 100; //v1[0] 表达式 转换成 运算符函数 v1.operator[](0)
    //char str[10]
    Vector<char> v2(12);
    v2[0] = 'a';
    //char str[3][4]
    char(*str)[4] = (char(*)[4])v2.addr();//v2.addr返回的是指针,将长度为十二的char数组强制转化为二维数组三行四列
    return 0;
}

设计一个单向链表类模板? --万能版链表

1. 先做一个整形的链表类

#include <iostream>

//整型单向非循环链表
class ForwardList{
    friend ostream& operator<<(ostream &out,ForwardList<T>&ra);
public:
    typedef struct node{
        int data;
        struct node *next;
    }Node_t;

    ForwardList()
    {
        m_head = NULL;
        m_tail = NULL;
        m_size = 0;

    }
    ~ForwardList()
    {

    }
    //尾插
    void push_back(Tint data)
    {
        //申请结点内存空间并且初始化
        Node_t* newNode = new Node_t;

        newNode->data = data;
        newNode->next = NULL;

        //从无到有
        if(m_size == 0)
        {
            m_head = m_tail = newNode;
        }
        else{//从少到多
            m_tail->next = newNode;
            m_tail = newNode;
        }

        m_size++;
     }
    //尾删
    void pop_back()
    {
        if(m_size == 1)
        {
            delete m_tail;
            m_head = m_tail = NULL;
            m_size--;

            return;
        }

        //1、先找到尾结点的前一个结点
        Node_t *pre = m_head;
        while(pre)
        {
            if(pre->next == m_tail)
                break;
            pre = pre->next;
        }
        //2、删除尾结点
        delete m_tail;

        //3、更新尾结点
        m_tail = pre;
        //4、尾结点断链接
        pre->next = NULL;

        m_size --;
    }
    void clear()
    {
        Node_t *p = m_head;
        while(p)
        {
            Node_t *delNode = p;
            p = p->next;

            delete delNode;
        }

        m_head = m_tail = NULL;
        m_size = 0;
    }
    int size()
    {
        return m_size;
    }
private:
    Node_t* m_head;
    Node_t* m_tail;
    int m_size;
    //把链表的增删查改排序全部封装在类里面
};

ostream& operator<<(ostream &out,ForwardList&ra)
{
    ForwardList::Node_t *p = ra.m_head;
    while(p)
    {
        out<<p->data<<"\t";
        p = p->next;
    }
}

int main()
{
    ForwardList f1;
    f1.push_back(10);
    f1.push_back(20);
    f1.push_back(30);
    f1.push_back(40);
    cout<<f1<<endl;
    return 0;
}

2. 将整形链表类改为万能版

template<class T>
class ForwardList{
public:
    typedef struct node{
        T data;
        struct node *next;
    }Node_t;

    ForwardList()
    {
        m_head = NULL;
        m_tail = NULL;
        m_size = 0;
    }
    ~ForwardList()
    {
    }
    //尾插
    void push_back(T data)
    {
        //申请结点内存空间并且初始化
        Node_t* newNode = new Node_t;
        newNode->data = data;
        newNode->next = NULL;
        //从无到有
        if(m_size == 0)
        {
            m_head = m_tail = newNode;
        }
        else{//从少到多
            m_tail->next = newNode;
            m_tail = newNode;
        }
        m_size++;
     }
    //尾删
    void pop_back()
    {
        if(m_size == 1)
        {
            delete m_tail;
            m_head = m_tail = NULL;
            m_size--;
            return;
        }

        //1、先找到尾结点的前一个结点
        Node_t *pre = m_head;
        while(pre)
        {
            if(pre->next == m_tail)
                break;
            pre = pre->next;
        }
        //2、删除尾结点
        delete m_tail;

        //3、更新尾结点
        m_tail = pre;
        //4、尾结点断链接
        pre->next = NULL;

        m_size --;
    }
    void clear()
    {
        Node_t *p = m_head;
        while(p)
        {
            Node_t *delNode = p;
            p = p->next;

            delete delNode;
        }

        m_head = m_tail = NULL;
        m_size = 0;
    }
    int size()
    {
        return m_size;
    }
private:
    Node_t* m_head;
    Node_t* m_tail;
    int m_size;
    //把链表的增删查改排序全部封装在类里面
};

class Student{
public:
    Student()
    {

    }
    Student(const char*n,int a,float s)
    {
        strcpy(name,n);
        age = a;
        score = s;
    }

private:
    char name[256];
    int age;
    float score;
};
template<class T>
ostream& operator<<(ostream &out,ForwardList<T>&ra)
{
    typename ForwardList<T>::Node_t *p = ra.m_head;
    while(p)
    {
        out<<p->data<<"\t";
        p = p->next;
    }
}

int main()
{
    ForwardList<int> f1;
    f1.push_back(10);
    f1.push_back(20);
    f1.push_back(30);
    f1.push_back(40);
    cout<<f1<<endl;

    ForwardList<Student> f2;
    f2.push_back(Student("zhang3",22,100));
    f2.push_back(Student("zhang4",22,100));
    f2.push_back(Student("zhang5",22,100));

    return 0;
}

3. 将他放入hpp里,hpp是专门存放模板的,新建一个forwardlist.hpp,将模板移到hpp里

#ifndef FORWARDLIST_H
#define FORWARDLIST_H

#include <iostream>

//整型单向非循环链表
template<class T>
class ForwardList{
public:
    typedef struct node{
        T data;
        struct node *next;
    }Node_t;

    ForwardList()
    {
        m_head = NULL;
        m_tail = NULL;
        m_size = 0;

    }
    ~ForwardList()
    {

    }
    //尾插
    void push_back(T data)
    {
        //申请结点内存空间并且初始化
        Node_t* newNode = new Node_t;

        newNode->data = data;
        newNode->next = NULL;

        //从无到有
        if(m_size == 0)
        {
            m_head = m_tail = newNode;
        }
        else{//从少到多
            m_tail->next = newNode;
            m_tail = newNode;
        }

        m_size++;
     }
    //尾删
    void pop_back()
    {
        if(m_size == 1)
        {
            delete m_tail;
            m_head = m_tail = NULL;
            m_size--;

            return;
        }

        //1、先找到尾结点的前一个结点
        Node_t *pre = m_head;
        while(pre)
        {
            if(pre->next == m_tail)
                break;
            pre = pre->next;
        }
        //2、删除尾结点
        delete m_tail;

        //3、更新尾结点
        m_tail = pre;
        //4、尾结点断链接
        pre->next = NULL;

        m_size --;
    }
    void clear()
    {
        Node_t *p = m_head;
        while(p)
        {
            Node_t *delNode = p;
            p = p->next;

            delete delNode;
        }

        m_head = m_tail = NULL;
        m_size = 0;
    }
    int size()
    {
        return m_size;
    }
private:
    Node_t* m_head;
    Node_t* m_tail;
    int m_size;
};
#endif // FORWARDLIST_H

文章来源:https://blog.csdn.net/weixin_59669309/article/details/135375889
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。