c++ template模板

函式樣板

函数模板的声明形式如下:

template <class identifier> function_declaration;
template <typename identifier> function_declaration;
template < 樣板參數型態 樣板參數名 , …其他樣板參數 >
原型回傳型態 函式名稱(參數型態 原型參數名, ...)
{
程式碼;
} 

这里写图片描述

函式樣板:參數型態可用關鍵字 classtypename 表示泛用型態 (即任何型態);或是一個已宣告的資料型態,如int 與自定類。
原型中的參數型態若是已宣告的資料型態,則是一種特殊化的函式樣板。

#include <iostream>
using namespace std;
int Add(int a, int b)
{
return a + b;
}
template <class T>
T Add(T a, T b)
{
return a + b;
} 
int main()
{
int c1;
double c2;
c1 = Add(10, 20);
c2 = Add(10.3, 20.4);
return 0;
}

C++函式樣板寫一個泡沫排序法(BubbleSort):

#include <iostream>
#include <string>
using namespace std;

template <class T>
void BubbleSort(int n, T A[])
{
    T temp;
    int i, j;
    for (i = n - 1; i>1; i--)   //for(i=0; i<n-1; i++)
    {
        for (j = 0; j<i; j++)   //for(j=0; j<n-1; j++)
        {
            if (A[j] > A[j + 1])
            {
                temp = A[j];
                A[j] = A[j + 1];
                A[j + 1] = temp;
            }
        }
    }
}

template <class T>
void PrintArray(int n, T A[])
{
    int i;
    for (i = 0; i<n; i++)
        cout << A[i] << " ";
    cout << endl;
}

int main()
{
    int n = 5;
    int A1[5] = { 12,33,2,4,22 };
    double A2[5] = { 12.43, 12.33, 2.4 ,4.66 ,22.1 };
    char A3[5] = { 'G','B','H','Z','Q' };
    string A4[5] = { "Joe", "John", "Andy", "Mary", "Bob" };

    BubbleSort(n, A1);
    BubbleSort(n, A2);
    BubbleSort(n, A3);
    BubbleSort(n, A4);
    PrintArray(n, A1);
    PrintArray(n, A2);
    PrintArray(n, A3);
    PrintArray(n, A4);

    system("pause");
    return 0;
}

输出:
2 4 12 22 33
2.4 4.66 12.33 12.43 22.1
B G H Q Z
Andy Bob Joe John Mary
请按任意键继续. . .

類別樣板

template < 樣板參數型態 樣板參數名 , … >
class 類別名稱<部份特殊化型態,…>
{
原型回傳型態 函式名稱(參數型態 原型參數名, ...) ;
參數型態 變數名稱;
}
template < 樣板參數型態 樣板參數名 , … >
原型回傳型態 類別名稱< 樣板參數型態 樣板參數名 , … > ::函式名稱<部份特殊化型態,…>
{
程式碼;
}
類別名稱

例子:

#include <iostream>
#include <string>
using namespace std;
class myClass
{
public:
void display(int n)
{
a = n;
cout << a << endl;
}
int a;
}; 
template <class T>
class myTClass
{
public:
void display(T n)
{
a = n;
cout << a << endl;
}
T a;
};
int main()
{
myTClass<int> a;
myTClass<double> x;
a.display(10);
x.display(10.4);
return 0;
}

例子2:

#include <iostream>
#include <string>
using namespace std;
class myClass
{
public:
void display(int n, char ch)
{
a = n;
b = ch;
cout << a << " " << b << endl;
}
int a;
char b;
}; 
template <class T1, class T2>
class myTClass
{
public:
void display(T1 n, T2 ch)
{
a = n;
b = ch;
cout << a << " " << b << endl;
}
T1 a;
T2 b;
};
int main()
{
myTClass<int, char> a;
myTClass<double, double> x;
a.display(10, 'A');
x.display(10.4, 20.5);
return 0;
} 

使用鏈結串列範例為例, 製作鏈結串列樣板:

// 永远.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"


#include <numeric>      // Need accumulate()




#include <iostream>
#include <string>
#include <conio.h>
#include <stdlib.h>
using namespace std;


template <class T>
class node
{
public:
    T data;
    node<T> *next;
};

template <class T>
class LinkedList
{
public:
    LinkedList();
    void insert(T &value);
    void remove(T &value);
    void find(T &value);
    void print();
private:
    node<T> *getnode();
    void freenode(node<T> *p);
    void insert_node(node<T> *ptr, T &value);
    void delete_node(node<T> *ptr);
    node<T> *find_node(T &num);
    int length();

    node<T> *head;
    node<T> *tail;
};

template <class T>
LinkedList<T>::LinkedList()
{
    head = NULL;
    tail = NULL;
}

template <class T>
node<T> *LinkedList<T>::getnode() /* 此函數產生一個新節點 */
{
    node<T> *p;
    p = new node<T>;
    if (p == NULL)
    {
        cout << "記憶體不足" << endl;
        exit(1);
    }
    return(p);
}

template <class T>
void LinkedList<T>::freenode(node<T> *p) /* 此函數將節點還給記憶體 */
{
    delete p;
}

template <class T>
void LinkedList<T>::insert_node(node<T> *ptr, T &value)
{
    node<T> *new_node;            /* 新節點指標變數 */
    new_node = getnode();    /* 建立新節點,取得一個可用節點 */
    new_node->data = value; /* 建立節點內容 */
    new_node->next = NULL; /* 設定指標初值 */

    if (ptr == NULL) /* 指標ptr是否是NULL */
    {
        /* 第一種情況: 插入第一個節點 */
        new_node->next = head; /* 新節點成為串列開始 */
        head = new_node;
    }
    else
    {
        if (ptr->next == NULL) /* 是否是串列結束 */
                               /* 第二種情況: 插入最後一個節點 */
            ptr->next = new_node; /* 最後指向新節點 */
        else
        {
            /* 第三種情況: 插入成為中間節點 */
            new_node->next = ptr->next; /* (3) 新節點指向下一節點 (3)*/
            ptr->next = new_node; /* 節點ptr指向新節點 (4)*/
        }
    }
}

template <class T>
void LinkedList<T>::delete_node(node<T> *ptr)
{
    node<T> *previous; /* 指向前一節點 */
    if (ptr == head) /* 是否是串列開始 */
                     /* 第一種情況: 刪除第一個節點 */
    {
        head = head->next;
    }
    else
    {
        previous = head;
        while (previous->next != ptr) /* 找節點ptr的前節點 */
            previous = previous->next;
        if (ptr->next == NULL) /* 是否是串列結束 */
                               /* 第二種情況: 刪除最後一個節點 */
            previous->next = NULL; /* 最後一個節點 */
        else
            /* 第三種情況: 刪除中間節點 */
            previous->next = ptr->next; /* 圖(3)之步驟(1) */
    }
    freenode(ptr); /* 此函數將節點歸還給記憶體 */
}
template <class T>
node<T> *LinkedList<T>::find_node(T &num)
{
    node<T> *ptr;
    ptr = head; /* 指向串列起始 */
    while (ptr != NULL) /* 走訪串列 */
    {
        if (ptr->data == num) /* 找尋data */
            return (ptr);
        ptr = ptr->next; /* 指向下一節點 */
    }
    return (ptr);
}
template <class T>
int LinkedList<T>::length() /* 此函數計算節點之鏈結長度 */
{
    int num = 0;
    node<T> *q = head;
    while (q != NULL)
    {
        num++;
        q = q->next;
    }
    return(num);
}

template <class T>
void LinkedList<T>::insert(T &value)
{
    if (head == NULL)
    {
        head = getnode();
        head->data = value;
        head->next = NULL;
        tail = head;
    }
    else
    {
        insert_node(tail, value);
        tail = tail->next;
    }
    cout << "資料插入成功!" << endl;
}

template <class T>
void LinkedList<T>::remove(T &value)
{
    node<T> *prev, *ptr;
    ptr = find_node(value);
    if (ptr != NULL)
    {
        if (length() == 1)
        {
            delete_node(ptr);
            tail = NULL;
        }
        else if (ptr->next == NULL)
        {
            prev = head;
            while (prev->next != ptr)
                prev = prev->next;
            delete_node(ptr);
            tail = prev;
        }
        else
        {
            delete_node(ptr);
        }
        cout << "資料已刪除!" << endl;
    }
    else
    {
        cout << "無此資料!" << endl;
    }
}

template <class T>
void LinkedList<T>::find(T &value)
{
    node<T> *ptr;
    ptr = find_node(value);
    if (ptr != NULL)
    {
        cout << "找到節點資料: " << ptr->data << endl;
    }
    else
    {
        cout << "找不到該節點資料" << endl;
    }
}

template <class T>
void LinkedList<T>::print()
{
    node<T> *q = head;
    while (q != NULL)
    {
        cout << q->data << " ";
        q = q->next;
    }
    cout << endl;
}

int main()
{
    LinkedList<int> list;
    int value;
    char key;
    while (1)
    {
        cout << "i: 插入" << endl;
        cout << "d: 刪除" << endl;
        cout << "f: 尋找" << endl;
        cout << "l: 列印" << endl;
        cout << "e: 離開" << endl;
        cout << "> ";
        key = _getche();
        cout << endl;
        switch (key)
        {
        case 'i':
            cout << "輸入插入資料內容: ";
            cin >> value;
            list.insert(value);
            break;
        case 'd':
            cout << "輸入刪除資料內容: ";
            cin >> value;
            list.remove(value);
            break;
        case 'f':
            cout << "輸入尋找資料內容: ";
            cin >> value;
            list.find(value);
            break;
        case 'l':
            list.print();
            break;
        case 'e':
            cout << "ByeBye!" << endl;
            exit(0);
        default:
            cout << "輸入值錯誤!" << endl;
        }
        cout << endl;
    }
    return 0;
}

参考:
http://homepage.ntu.edu.tw/~d02922022/AdvC/ppt/Part%202/08%20C++%E6%A8%A3%E6%9D%BF(Template).pdf

https://blog.csdn.net/qq_35637562/article/details/55194097

猜你喜欢

转载自blog.csdn.net/nockinonheavensdoor/article/details/80844709