C++知識點隨筆(六):模板

一、函數模板

C++中模板和重載的區別:
模板是除了類型全都相同的情況下可以使用;而重載是裏面的功能也有不同時使用的。
下面看一個函數模板的使用實例:

#include<iostream>
using namespace std;

typedef struct _Node
{
    int m_a;
    char* m_str;
}Node;

bool leftNodeBig(Node a, Node b) //結構體從大到小排
{
    return (a.m_a < b.m_a);
}

template <typename T>   //整形從大到小排
bool leftBig(T t, T w)
{
    return (t < w); 
}

template <typename T>   //整形從小到大排
bool leftSmall(T t, T w)
{
    return (t > w); 
}

template <typename T>
void Bubble(T* arr, int nLength, bool (*pFun)(T a, T b)) //注意函數指針格式
{
    for(int i=0;i<nLength-1;i++)
    {
        for (int j=0;j<nLength-1-i;j++)
        {
            if((*pFun)(arr[j], arr[j+1]))
            {
                //注意這裏不能通過 ^ 交換了,因爲結構體無法這樣交換
                //arr[j] = arr[j] ^ arr[j+1]; 
                //arr[j+1] = arr[j] ^ arr[j+1];
                //arr[j] = arr[j] ^ arr[j+1];
                T temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }
}

template <typename T>
void Show(T* arr, int nLength)
{
    for(int i=0;i<nLength;i++)
    {
        cout << arr[i] << " ";
    }
    cout << endl;
}

ostream& operator<<(ostream& os, Node& node) //重載操作符保證結構體正常輸出
{
    os << node.m_a << " " << node.m_str;
    return os;
}


int main()
{
    int arr[] = {1,3,5,7,9,0,8,6,4,2};
    Bubble(arr, 10, &leftBig<int>);
    Show(arr, 10);

    char str[] = {'b','e','f','y','s','a','c','d','l','z'};
    Bubble(str, 10, &leftSmall<char>);
    Show(str, 10);

    Node arrNode[] = {{10,"hehe"},{9,"haha"},{100,"yaya"}};
    Bubble(arrNode, 3, &leftNodeBig);
    Show(arrNode,3);

    system("pause");
    return 0;
}

二、類模板

類模板要注意:只要我們定義了類模板的 template,那麼我們只要除了這個類,一見到這個類名,就要加:

CPeople<>

其實函數模板也是一樣的,定義了函數模板之後,我們在外面使用這個函數的時候也要添加類型,不加同樣會報錯,就像我們上面寫的:

Bubble(arr, 10, &leftBig<int>);

下面我們看一段類模板的使用實例:

#include<iostream>
using namespace std;

template<typename T>
class CPeople
{
public:
    //注意使用初始列表給成員變量初始化,因爲我們傳進來的模板T有可能是對象,前面我們也學習過,如果在類中定義一個有參數的類,那麼一定要在初始化列表中給它傳參。
    CPeople(T t):m_t(t) 
    {
    }
    virtual void Show() //虛函數,調用子類重寫的 Show()
    {
        cout << this->m_t << endl;
    }
protected:
    T m_t;
};

template<typename P, typename Q>
class CChinese : public CPeople<Q>
{
public:
    CChinese(P p, Q q):CPeople<Q>(q), m_p(p) //這裏一定要使用初始化列表
    {
    }
    void Show()
    {
        //如果我們不重載CAA類的‘<<’操作符的話,這一句就會報錯
        cout << m_t << " " << this->m_p << endl;
    }
private:
    P m_p;
};

template<typename M>
class CAA
{
public:
    CAA(M m)
    {
        this->m_m = m;
    }
public:
    M m_m;
};

template<typename N>
ostream& operator<<(ostream& os, CAA<N>& aa)  //重載CAA類的操作符
{
    os << aa.m_m;
    return os;
}

int main()
{
    //父類指針指向子類對象,子類實現<double, char*>類型的模板
    CPeople<char*> *p1 = new CChinese<double, char*>(123.456, "hello");
    p1->Show();

    //父類指針指向子類對象,子類將對象作爲模板
    CAA<double> caa(56.78);
    CPeople<CAA<double>> *p2 = new CChinese<double, CAA<double>>(123.456, caa);
    p2->Show();

    //父類指針指向子類對象,子類將兩個對象作爲模板
    CAA<char*> *cbb = new CAA<char*>("hello world!");
    CPeople<CAA<char*>> *p3 = new CChinese<CAA<double>,CAA<char*>>(caa, *cbb);
    p3->Show();

    system("pause");
    return 0;
}
發佈了27 篇原創文章 · 獲贊 3 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章