多功能的模板


1 为什么要用模板

    在使用之前我们可以探究一下为什么要用模板。首先,模板是泛型编程的基础。所谓泛型编程就是编写与类型无关的逻辑代码,是一种复用的方式。模板分为模板函数和模板类。

例如:


  • 模板函数

假设现在要实现一个比较两个数是否相等的重载函数。

bool IsEqual (int left, int right)
{
     return left == right;
}
bool IsEqual (const string& left , const string& right)
{
     return left == right;
}
void test1 ()
{
     string s1 ("s1"), s2("s2");
     cout<<IsEqual (s1, s2)<<endl;
     cout<<IsEqual (1,1)<<endl;
}

【注】如果还要比较int/char等等类型就都要分别实现一下,相似的代码重复度非常高。


2 怎么用模板实现seqlist

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<string>
#pragma warning(disable:4018)

using namespace std;
typedef int DataType;
template <typename T>
class seqlist
{
public:
    seqlist()
        :_data(NULL)
        ,_size(0)
        ,_capacity(0)
{
    CheckCapacity();
}
    
    /*seqlist(const T& d)
        :_data(d._data)
        ,_size(d._size)
        ,_capacity (d._capacity)
    {

}
    }*/
    ~seqlist()
    {
        if(_data!=NULL)
        delete [] _data;
    }
public:
    void CheckCapacity()
    {
        if(_size == _capacity)
        {
            T* tmp=new T[2*_capacity+3];
            memcpy(tmp,_data,_size*_sizeof(T));
            delete _data;
            _data = tmp;
            _capacity =2*_capacity+3 ;
        }    
    }
public:
    void PushBack(const T& d);
    void PopBack();
    void PushFront(const T& d);
    void PopFront();
    void Insert(size_t pos, const T& x);
    void Erase(size_t pos);
    int Find(const T& x);
    void PrintSeqList();
    void Print()
    {
        int i=0;
        for(i=0;i<_size;i++)
        {
            cout<<_data[i]<<" "
        }
        cout<<endl;
    }
private:
    T* _data;
    int _size;
    int _capacity;
};
template <typename T>
void seqlist<T>:: PushBack(const T& d)
{
    CheckCapacity();
    _data[_size] = d;
    _size++;
}
template <typename T>
void seqlist<T>:: PopBack()
{
    if(_data == NULL)
    {
        return;
    }
    _size--;
    _capacity--;
}
template <typename T>
void seqlist<T>:: PushFront(const T& d)
{
    CheckCapacity();
    for(i=_size;i>0;i--)
    {
        _data[i] = _data[i-1];
    }
    _data[0] = d;
    ++_size;
}
template <typename T>
void seqlist<T>::PopFront()
{
    int i=0;
    for(i=0;i<_size;i++)
    {
        _data[i-1] = _data[i];
    }
    --_size;
}
template<typename T>
void seqlist<T>::Insert(size_t pos, const T& x)
{
    CheckCapacity();
    int i=0;
    for(i=_size;i>pos,--i)
    {
        _data[i] = _data[i-1];
    }
    _data[i]=d;
    ++_size;
}
template<typename T>
void seqlist<T>::Erase(size_t pos)
{
    int i = 0;
    for(i=pos;i<_size-1;i++)
    {
        _data[i] = _data[i+1]
    }
    --_size;
}
template<typename T>
int seqlist<T>::Find(const T& x)
{
    int i=0;
    for(i=0;i<_szie;i++)
    {
        if(_data[i]==x)
            return i;
    }
    return -1;
}
void Test1()
{
    seqlist<int> s1;
    s1.PushBack(1);
    s1.PushBack(2);
    s1.PushBack(3);
    s1.PushBack(4);
}
void Test2()
{
    seqlist<int> s1;
    s1.PopBack();
}
void Test3()
{
    seqlist<int> s1;
    s1.PopFront();
}
void Test3()
{
    seqlist<int> s1;
    s1.PushFront(1);
    s1.PushFront(2);
    s1.PushFront(3);
    s1.PushFront(4);
}
template <typename T>
int main()
{
    Test1();
    s1.Print();
    return 0;
}