Giskard

(二十九)模板

2018-11-01

函数模板

  • 为了表达一个通用的算法或逻辑
//求最大值
int max(int arr[],int len)
{
    ...
}
double max(...)
{
    ...
}
Object max(...)
{
    ...
}

上面三个要表达的算法都是相同的,唯一区别就是参与运算的数据类型不同,使用函数模板可以将这三个简化为一个

template <typename T>

T max(T arr[],int len)
{
    T val = arr[0];
    for(int i=1;i<len;i++)
    {
        if(arr[i]>val)
        {
            val = arr[i];
        }
    }
    return val;
}

int main()
{
    int arr[4] = {1,2,3,4};
    int result = max<int>(arr,4);  //max<int>()表示对模板实例化,用int代替T,直接调用max(arr,4)是不正确的
    return 0;
}

类模板

有的类只描述了一些通用的算法和逻辑,可以用类模板代替。比如对于链表来说,无论数据类型是什么,其插入删除遍历算法是一样的

template <typename T>

class List
{
public:
    void insert(const T& node)
    {

    }
    int length()
    {

    }
}

List<int> mylist; //对类模板List的实例化
int len = mylist.lengh;
  • 与普通的类写法不一样,类模板的声明和定义都要写在*.h文件里,不建议使用分离式写法。

模板参数

template <int N,typename T> //尖括号内有多个参数

T* create()
{
    T* str = new T[N];
    return str;
}

//等价于

template <typename T> 

T* create(int N)
{
    T* str = new T[N];
    return str;
}

实例:栈

///Stack.h
template <typename T>
class Stack
{
private:
    T* m_buffer;
    int m_maxsize;
    int m_size;
public:
    Stack(int maxsize)
    {
        m_maxsize = maxsize;
        m_buffer = new T[maxsize];
        m_size;   //初始长度为0
    }
    ~Stack()
    {
        delete[] m_buffer;
    }

    //推入元素
    bool push(const T& value)
    {
        if(m_size>=m_maxsize) return false;
        m_buffer[m_size] = value;
        m_size++;
        return true;
    }

    //弹出元素
    T pop()
    {
        T last = m_buffer[m_size-1];
        m_size--;
        return last;
    }

    //得到栈顶元素
    const T& top()
    {
        return m_buffer[m_size-1];
    }

    int size()
    {
        return m_size;
    }
}

///main.cpp
#include "Stack.h"
{
    Stack<int>mystack(10);
    mystack.push(0);
    mystack.push(1);
    ...
    while(mystack.size()>0)
    {
        int n = mystack.pop();
    }
}
Tags: C/C++