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

目录

类模板

思考

解决方法 创建类模板

 实战

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

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

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

  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
面向对象程序设计课程作业 1. 请创建一个数据类型为T的链表类模板List,实现以下成员函数: 1) 默认构造函数List(),将该链表初始化为一个空链表(10分) 2) 拷贝构造函数List(const List& list),根据一个给定的链表构造当前链表(10分) 3) 析构函数~List(),释放链表中的所有节点(10分) 4) Push_back(T e)函数,往链表最末尾插入一个元素为e的节点(10分) 5) operator<<()友元函数,将链表的所有元素按顺序输出(10分) 6) operator=()函数,实现两个链表的赋值操作(10分) 7) operator+()函数,实现两个链表的连接,A=B+C(10分) 2. 请编写main函数,测试该类模板的正确性: 1) 用List模板定义一个List类型的模板类对象int_listB,从键盘读入m个整数,调用Push_back函数将这m个整数依次插入到该链表中;(4分) 2) 用List模板定义一个List类型的模板类对象int_listC,从键盘读入n个整数,调用Push_back函数将这n个整数依次插入到该链表中;(4分) 3) 用List模板定义一个List类型的模板类对象int_listA,调用List的成员函数实现A = B + C;(4分) 4) 用cout直接输出int_listA的所有元素(3分) 5) 用List模板定义List类型的模板类对象double_listA, double_listB, double_listC,重复上述操作。(15分) 3. 输入输出样例: 1) 输入样例 4 12 23 34 45 3 56 67 78 3 1.2 2.3 3.4 4 4.5 5.6 6.7 7.8 2) 输出样例 12 23 34 45 56 67 78 1.2 2.3 3.4 4.5 5.6 6.7 7.8
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值