1. 程式人生 > 其它 >模版-基礎

模版-基礎

類--模具

例項化出來的物件--模具做出來的產品

模版--模具的圖紙

模版--例項化--》類(模具)---例項化物件(產品)

一.函式模版

模板和特例化返回值一致,函式名一致,引數格式一致
模板型別是在編譯期進行確定,確定好模板型別之後例項化成具體的
函式/類,以供使用

模板是否都會例項化呢?
特例化會直接編譯,不用例項化
普通模板只有呼叫才會編譯
模板只有呼叫了才會例項化,會根據呼叫的型別例項化出對應的函
數/類
模板在編譯期間進行例項化

普通函式>特例化版本>模版

普通函式:整形,浮點型

template<typename T>
bool compare(T a, T  b)//比較  含參
{ cout << "bool compare(T a, T b) " << typeid(T).name() << endl;//進行輸出 // typeid(T).name() 輸出型別名 return a > b;//若為真 返回值 為假返回0 }

函式模板不能滿足個別的型別需求的情況下

函式模板的特例化

函式過載 是在編譯期確定需要呼叫的函式
函式模板 是在編譯期確定需要例項化的函式型別

函式模板例項化出來的多個函式之間是過載關係--包括函式模板的特例化

靜多型包含:編譯期間的多型 ,函式過載 ,模板

函式過載:

bool compare(int a, int b)
{
    cout << "bool compare(int a, int b)" << endl;
    return a > b;
}

bool compare(char a, char b)
{
    return a > b;
}

bool compare(const char* a,const char* b)//傳常量字串
{
    cout << "bool compare(const char* a,const char* b)" << endl;
    
return strcmp(a,b) > 0; }

特例化版本:

字串:

template<>
bool compare<const char*>(const char* a, const char* b)
{
    cout << "bool compare<const char*>(const char* a, const char* b)" << endl;
    return strcmp(a, b) > 0;
}

氣泡排序的模板特例化

寫const char*

普通:

template<typename ZPL>//先指定型別代表
void Msort(ZPL* arr, int len)
{
    if (NULL == arr)
    {
        return;
    }
    ZPL tmp = ZPL();//   相當於int tmp=0;

    for (int i = 0; i < len; i++)
    {
        for (int j = 0; j < len - i - 1; j++)
        {
            if (arr[j] < arr[j + 1])
            {
                tmp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = tmp;
            }
        }
    }
}

特例化:

template<>
void Msort<const char*>(const char** arr, int len)//const char* 又因為是陣列 *arr
{
    if (NULL == arr)
    {
        return;
    }
    const char* tmp = NULL;//進行指定

    for (int i = 0; i < len; i++)
    {
        for (int j = 0; j < len - i - 1; j++)
        {
            if (arr[j] && arr[j + 1])//判斷他兩同時不為空
            {
                if (strcmp(arr[j], arr[j + 1]) < 0)//const char* 時使用strcmp
                {
                    tmp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = tmp;
                }
            }
        }
    }
}

函式模版:

template<typename T>
class Arr
{
private:
    T* _arr;
    int _len;
    int _size;

    void revert()
    {
        _len = _len << 1;
        T* tmp = new T[_len];
        memset(tmp, T(), _len);
        for (int i = 0; i < _size; i++)
        {
            tmp[i] = _arr[i];
        }

        delete[]_arr;
        _arr = tmp;
    }
public:
    Arr(int len = 10);
    Arr(T* arr, int size);
    Arr(const Arr& src);
    ~Arr();
    Arr& operator=(const Arr& src);
    void push_back(T val);
    void sort();
    bool is_full()
    {
        return _size == _len;
    }

    int size()//排序時使用,可不使用友元
    {
        return _size;
    }

    T* get_arr()
    {
        return _arr;
    }

    //template<typename T>//字母T 可換其他字母
    //friend ostream& operator<<(ostream& out, Arr<T>& src);//T可換 
};

template<typename T>//重新定義T
Arr<T>::Arr(int len)//宣告作用域Arr<T>   上面是預設值,下面是引數
{
    _len = len;
    _arr = new T[_len];
    memset(_arr, T(), _len);//進行初始化  T型別  預設值為len
    _size = 0;
}

template<typename T>
Arr<T>::Arr(T* arr, int size)
{
    _len = size;
    _size = size;
    _arr = new T[_len];
    memset(_arr, T(), _len);
    for (int i = 0; i < _len; i++)
    {
        _arr[i] = arr[i];
    }
}

template<typename T>
Arr<T>::Arr(const Arr& src)//拷貝構造
{
    _len = src._len;
    _size = src._size;
    _arr = new  T[_len];
    memset(_arr, T(), _len);
    for (int i = 0; i < _size; i++)//防止淺拷貝
    {
        _arr[i] = src._arr[i];
    }
}

template<typename T>
Arr<T>::~Arr()
{
    delete[]_arr;
    _arr = NULL;
    _size = _len = 0;
}

template<typename T>
Arr<T>& Arr<T>::operator=(const Arr& src)//等號運算子
{
    if (&src == this)
    {
        return *this;
    }

    delete _arr;

    _len = src._len;
    _size = src._size;
    _arr = new  T[_len];
    memset(_arr, T(), _len);
    for (int i = 0; i < _size; i++)
    {
        _arr[i] = src._arr[i];
    }

    return *this;
}

template<typename T>
void Arr<T>::push_back(T val)//從後面放
{
    if (is_full())
    {
        revert();//申請空間
    }

    _arr[_size++] = val;
}

template<typename T>
void Arr<T>::sort()//排序
{
    T tmp = T();

    for (int i = 0; i < _size; i++)
    {
        for (int j = 0; j < _size - i - 1; j++)
        {
            if (_arr[j] < _arr[j + 1])
            {
                tmp = _arr[j];
                _arr[j] = _arr[j + 1];
                _arr[j + 1] = tmp;
            }
        }
    }
}





template<typename T>//重新定義T  (Arr<T>中的T)
ostream& operator<<(ostream& out, Arr<T>& src)//類外輸出運算子過載
{
    for (int i = 0; i < src.size(); i++)
    {
        cout << src.get_arr()[i] << " ";
    }
    cout << endl;
    return out;
}