最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺析C++中模板的那點(diǎn)事

 更新時(shí)間:2013年09月24日 10:15:12   作者:  
C++中的模板可分為函數(shù)模板和類模板,而把函數(shù)模板的具體化稱為模板函數(shù),把類模板的具體化成為模板類。下面讓我們分別看看什么是函數(shù)模板和類模板吧

1.什么是模板

假設(shè)現(xiàn)在我們完成這樣的函數(shù),給定兩個(gè)數(shù)x和y求式子x^2 + y^2 + x * y的值 .考慮到x和y可能是 int , float 或者double類型,那么我們就要完成三個(gè)函數(shù):

int fun(int x,int y);
float fun(float x,float y);
double fun(double x,double y);

并且每個(gè)fun函數(shù)內(nèi)部所要完成的操作也是極其的相似。如下:

復(fù)制代碼 代碼如下:

int fun(int x,int y)
{
    int tmp = x *x + y * y + x * y;
    return tmp;
}
float fun(float x,float y)
{
    float tmp = x *x + y * y + x * y;
    return tmp;
}
double fun(double x,double y)
{
    double tmp = x *x + y * y + x * y;
    return tmp;
}

可以看出,上面的三個(gè)函數(shù)體除了類型不一樣之外,其他的完全一樣,那么如果能夠只寫一個(gè)函數(shù)就能完成上面的三個(gè)函數(shù)的功能該多好呢?如果從這三個(gè)函數(shù)提煉出一個(gè)通用函數(shù),而它又適用于這三種不同類型的數(shù)據(jù),這樣會(huì)使代碼的重用率大大提高。實(shí)際上C++中的模板正好就是來(lái)解決這個(gè)問(wèn)題的。模板可以實(shí)現(xiàn)類型的參數(shù)化(把類型定義為參數(shù)),從而實(shí)現(xiàn)了真正的代碼可重用性。C++中的模板可分為函數(shù)模板和類模板,而把函數(shù)模板的具體化稱為模板函數(shù),把類模板的具體化成為模板類。下面讓我們分別看看什么是函數(shù)模板和類模板吧~~~

2.模板函數(shù)

實(shí)際上我們利用函數(shù)模板,只需要一個(gè)函數(shù)就可能完成上面的三個(gè)函數(shù)了,千言萬(wàn)語(yǔ)不如看代碼:

復(fù)制代碼 代碼如下:

#include <iostream>

using namespace std;

template <typename T>
T fun(T x,T y)
{
    T tmp = x *x + y * y + x * y;
    return tmp;
}
int main()
{
    int x1 = 1,y1 = 4;
    float x2 = 1.1 , y2 = 2.2;
    double x3 = 2.0 , y3 = 3.1;
    cout<<fun(x1,y1)<<endl;
    cout<<fun(x2,y2)<<endl;
    cout<<fun(x3,y3)<<endl;
    return 0;
}


運(yùn)行結(jié)果:

如此利用模板,我們很輕而易舉的達(dá)到了我們的目的,而這也大大的提高了代碼的可重用性,這也讓我們想起了STL中的那些算法了吧,這些算法使用多種的數(shù)據(jù)類型。實(shí)際上STL即使模板的重要應(yīng)用了。

現(xiàn)在我們想,如果上面的代碼這樣調(diào)用fun(x1,y2)會(huì)怎么樣呢?點(diǎn)擊編譯會(huì)出現(xiàn)這樣的錯(cuò)誤:

可以看到編譯編譯出現(xiàn)問(wèn)題的是fun(x1,y2),說(shuō)的意思就是沒有對(duì)應(yīng)的函數(shù),要么x1和y2都是int型,要么x1和y2都是float型。那么我為什么要說(shuō)一下這樣一種情況呢?主要是為了引出模板也可以同時(shí)使用兩個(gè):

復(fù)制代碼 代碼如下:

#include <iostream>

using namespace std;


template <typename T1 , typename T2>
T2 fun(T1 x,T2 y)
{
    T2 tmp = x *x + y * y + x * y;
    return tmp;
}
int main()
{
    int x1 = 1,y1 = 4;
    float x2 = 1.1 , y2 = 2.2;
    double x3 = 2.0 , y3 = 3.1;
    cout<<fun(x1,y1)<<endl;
    cout<<fun(x2,y2)<<endl;
    cout<<fun(x3,y3)<<endl;
    cout<<fun(x1,y2)<<endl;
    return 0;
}


運(yùn)行結(jié)果:

當(dāng)使用兩個(gè)模板時(shí),為什么fun(x1,y1)也能正確運(yùn)行呢?因?yàn)楫?dāng)進(jìn)行這個(gè)調(diào)用時(shí),T1 = int ,T2 = int。所以這種調(diào)用也是沒有問(wèn)題的。

提到函數(shù)想到重載是很自然的吧,那么模板函數(shù)能不能重載呢?顯然是能的了,還是看代碼:

復(fù)制代碼 代碼如下:

#include <iostream>

using namespace std;


template <typename T1 , typename T2>
T2 fun(T1 x,T2 y)
{
    cout<<"調(diào)用了兩個(gè)個(gè)參數(shù)的 fun 函數(shù) ^^ "<<endl;
    T2 tmp = x *x + y * y + x * y;
    return tmp;
}
template <typename T>
T fun(T x , T y , T z)
{
    cout<<"調(diào)用了三個(gè)參數(shù)的 fun 函數(shù) ^^ "<<endl;
    T tmp = x * x + y * y + z * z + x * y * z;
    return tmp;
}
int main()
{
    int x1 = 1 , y1 = 4 , z1 = 5;
    float x2 = 1.1 , y2 = 2.2;
    double x3 = 2.0 , y3 = 3.1;
    cout<<fun(x1,y1)<<endl;
    cout<<fun(x2,y2)<<endl;
    cout<<fun(x3,y3)<<endl;
    cout<<fun(x1,y2)<<endl;
    cout<<fun(x1,y1,z1)<<endl;
    return 0;
}


運(yùn)行結(jié)果:

從結(jié)果已經(jīng)能看出來(lái)模版函數(shù)的重載是沒有任何問(wèn)題的了。那么模板函數(shù)和非模板函數(shù)之間是否能夠重載呢??

復(fù)制代碼 代碼如下:

#include <iostream>

using namespace std;

template <typename T>
T fun(T x,T y)
{
    cout<<"調(diào)用了模板函數(shù) ^^ "<<endl;
    T tmp = x * x + y * y + x * y;
    return tmp;
}
int fun(int x,int y)
{
    cout<<"調(diào)用了非模板函數(shù) ^^ "<<endl;
    int tmp = x * x + y * y + x * y;
    return tmp;
}

int main()
{
    int x1 = 1 , y1 = 4;
    float x2 = 1.1 , y2 = 2.2;
    cout<<fun(x1,y1)<<endl;
    cout<<fun(x2,y2)<<endl;
    return 0;
}


運(yùn)行結(jié)果:

看以看出模版函數(shù)和非模板函數(shù)也是可能重載的,那么重載函數(shù)的調(diào)用順序是怎么樣的呢?實(shí)際上是先查找非模板函數(shù),要有嚴(yán)格匹配的非模板函數(shù),就調(diào)用非模板函數(shù),找不到適合的非模板函數(shù)在和模板函數(shù)進(jìn)行匹配。

到這里,關(guān)于模板就說(shuō)這些吧~~~~

3.模板類

要是理解了模版函數(shù),模板類就相當(dāng)?shù)暮?jiǎn)單了,只不過(guò)模版函數(shù)是對(duì)函數(shù)中的類型使用模板,而模板類是對(duì)類中的類型使用模板,這我就不多說(shuō)了,下面的代碼是我以前利用模板寫的單鏈表,這個(gè)是模板的典型應(yīng)用:(測(cè)試過(guò))

復(fù)制代碼 代碼如下:

#include <stdio.h>
#include <iostream.h>

template <class T>
struct SLNode
{
    T data;
    SLNode<T> *next;
    SLNode(SLNode<T> *nextNode=NULL)
    {
        next = nextNode;
    }
    SLNode(const T &item,SLNode<T> *nextNode=NULL)
    {
        data = item;
        next = nextNode;
    }
};

template <class T>
class SLList
{
private:
    SLNode<T> *head;
    SLNode<T> *tail;
    SLNode<T> *currptr;
    int size;
public:
    SLList();
    SLList(const T &item);
    ~SLList();
    bool IsEmpty()const;
    int Length()const;
    bool Find(int k,T &item)const;
    int Search(const T &item)const;
    void InsertFromHead(const T &item);
    void InsertFromTail(const T &item);
    bool DeleteFromHead(T &item);
    bool DeleteFromTail(T &item);
    void Insert(int k,const T &item);
    void Delete(int k,T &item);
    void ShowListMember();
};
//構(gòu)造函數(shù)
template <class T>
SLList<T>::SLList()
{
    head = tail = currptr = new SLNode<T>();
    size = 0;
}
//構(gòu)造函數(shù)
template <class T>
SLList<T>::SLList(const T &item)
{
    tail = currptr = new SLNode<T>(item);
    head = new SLNode<T>(currptr);
    size = 1;
}
//析構(gòu)函數(shù)
template <class T>
SLList<T>::~SLList()
{
     SLNode<T> *temp;
    while(!IsEmpty())
    {
        temp = head->next;
        head->next = temp->next;
        delete temp;

    }
}
//判斷鏈表是否為空
template <class T>
bool SLList<T>::IsEmpty()const
{
    return head->next == NULL;
}
//返回鏈表的長(zhǎng)度
template <class T>
int SLList<T>::Length()const
{
     return size;
}
//查找第k個(gè)節(jié)點(diǎn)的閾值
template <class T>
bool SLList<T>::Find(int k,T &item)const
{
    if(k < 1)
    {
        cout<<"illegal position !"<<endl;
    }
    SLNode<T> *temp = head;
    int count = 0;
    while(temp != NULL && count < k)
    {
        temp = temp->next;
        count++;
    }
    if(temp == NULL)
    {
        cout<<"The list does not contain the K node !"<<endl;
        return false;
    }
    item = temp->data;
    return true;
}
//查找data閾值為item是表的第幾個(gè)元素
template <class T>
int SLList<T>::Search(const T &item)const
{
    SLNode<T> *temp = head->next;
    int count = 1;
    while(temp != NULL && temp->data != item)
    {
        temp = temp->next;
        count++;
    }
    if(temp == NULL)
    {
        cout<<"The node does not exist !"<<endl;
        return -1;
    }
    else
    {
        return count;
    }
}
//從表頭插入
template <class T>
void SLList<T>::InsertFromHead(const T &item)
{   
    if(IsEmpty())
    {
        head->next = new SLNode<T>(item,head->next);
        tail = head->next;
    }
    else
    {
        head->next = new SLNode<T>(item,head->next);
    }
    size++;
}
//從表尾插入
template <class T>
void SLList<T>::InsertFromTail(const T &item)
{
    tail->next = new SLNode<T>(item,NULL);
    tail = tail->next;
    size++;
}
//從表頭刪除
template <class T>
bool SLList<T>::DeleteFromHead(T &item)
{
    if(IsEmpty())
    {
        cout<<"This is a empty list !"<<endl;
        return false;
    }
    SLNode<T> *temp = head->next;
    head->next = temp->next;
    size--;
    item = temp->data;
    if(temp == tail)
    {
        tail = head;
    }
    delete temp;
    return true;
}
//從表尾刪除
template <class T>
bool SLList<T>::DeleteFromTail(T &item)
{
    if(IsEmpty())
    {
        cout<<"This is a empty list !"<<endl;
        return false;
    }
    SLNode<T> *temp = head;
    while(temp->next != tail)
    {
        temp = temp->next;
    }
    item = tail->data;
    tail = temp;
    tail->next=NULL;
    temp = temp->next;
    delete temp;
    size--;
    return true;
}
//在第k個(gè)節(jié)點(diǎn)后插入item值
template <class T>
void SLList<T>::Insert(int k,const T &item)
{
    if(k < 0 || k > size)
    {
        cout<<"Insert position Illegal !"<<endl;
        return;
    }
    if(k == 0)
    {
        InsertFromHead(item);
        return;
    }
    if(k == size)
    {
        InsertFromTail(item);
        return;
    }
    SLNode<T> *temp = head->next;
    int count = 1;
    while(count < k)
    {
        count++;
        temp = temp->next;
    }
    SLNode<T> *p = temp->next;
    temp->next = new SLNode<T>(item,p);
    size++;
}
//刪除第k個(gè)節(jié)點(diǎn)的值,保存在item中
template <class T>
void SLList<T>::Delete(int k,T &item)
{
    if(k <= 0 || k > size)
    {
        cout<<"Ileegal delete position !"<<endl;
        return;
    }
    if(k == 1)
    {
        DeleteFromHead(item);
        return;
    }
    if(k == size)
    {
        DeleteFromTail(item);
        return;
    }
    SLNode<T> *temp = head->next;
    int count = 1;
    while(count < k-1)
    {
        count++;
        temp = temp->next;
    }
    SLNode<T> *p = temp->next;
    temp->next = p->next;
    p->next = NULL;
    item = p->data;
    delete p;
    size--;
}
template <class T>
void SLList<T>::ShowListMember()
{
    cout<<"List Member : ";
    SLNode<T> *temp = head->next;
    while(temp != NULL)
    {
        cout<<temp->data<<" ";
        temp = temp->next;
    }
    cout<<endl;
}

/*
1.引入了InsertFronHead,InsertFromTail,DeleteFromHead和DeleteFromTail用來(lái)實(shí)現(xiàn)Insert和Delete函數(shù),是一個(gè)比較好的方法。

2.SLNode(T &item,SLNode<T> *nextNode)這個(gè)構(gòu)造函數(shù)設(shè)計(jì)的非常巧妙,便于其他成員函數(shù)的實(shí)現(xiàn)。

3.插入,刪除分為:表頭,表尾,中間插入(刪除)三種情況
*/

int main()
{
    int item;
    SLList<int> list(12);

    list.Insert(0,11);
    cout<<"list number:"<<list.Length()<<endl;
    list.ShowListMember();

    list.Insert(2,14);
    cout<<"list number:"<<list.Length()<<endl;
    list.ShowListMember();

    list.Insert(2,13);
    cout<<"list number:"<<list.Length()<<endl;
    list.ShowListMember();

    list.Delete(2,item);
    cout<<"item = "<<item<<endl;
    cout<<"list number:"<<list.Length()<<endl;
    list.ShowListMember();

    list.Delete(1,item);
    cout<<"item = "<<item<<endl;
    cout<<"list number:"<<list.Length()<<endl;
    list.ShowListMember();

    list.Delete(2,item);
    cout<<"item = "<<item<<endl;
    cout<<"list number:"<<list.Length()<<endl;
    list.ShowListMember();
    return 0;
}


利用模板的好處是,SLList中的數(shù)據(jù)可以是任意的數(shù)據(jù)類型,這也就是泛型編程的概念了吧~~~~

相關(guān)文章

  • Qt正則表達(dá)式使用舉例

    Qt正則表達(dá)式使用舉例

    這篇文章主要給大家介紹了關(guān)于Qt正則表達(dá)式使用的相關(guān)資料,Qt中的正則表達(dá)式模式匹配功能由QRegExp類實(shí)現(xiàn),它完全支持Unicode,并可以應(yīng)用于字符串驗(yàn)證、搜索、查找替換和分割等場(chǎng)景,需要的朋友可以參考下
    2024-02-02
  • C++類的定義和對(duì)象的創(chuàng)建詳解

    C++類的定義和對(duì)象的創(chuàng)建詳解

    本篇文章重點(diǎn)講解了兩種創(chuàng)建對(duì)象的方式:一種是在棧上創(chuàng)建,形式和定義普通變量類似;另外一種是在堆上使用 new 關(guān)鍵字創(chuàng)建,必須要用一個(gè)指針指向它,下面和小編一起來(lái)學(xué)習(xí)下面為文章的內(nèi)容
    2021-09-09
  • C++中求組合數(shù)的各種方法總結(jié)詳解

    C++中求組合數(shù)的各種方法總結(jié)詳解

    本篇文章是對(duì)C++中的求組合數(shù)的各種方法進(jìn)行了詳細(xì)的介紹。需要的朋友參考下
    2013-05-05
  • Qt數(shù)據(jù)庫(kù)應(yīng)用之實(shí)現(xiàn)通用數(shù)據(jù)庫(kù)分頁(yè)

    Qt數(shù)據(jù)庫(kù)應(yīng)用之實(shí)現(xiàn)通用數(shù)據(jù)庫(kù)分頁(yè)

    數(shù)據(jù)庫(kù)分頁(yè)展示,在所有的涉及到數(shù)據(jù)庫(kù)記錄的項(xiàng)目中都是需要的。本文將利用Qt實(shí)現(xiàn)通用數(shù)據(jù)庫(kù)的分頁(yè)展示,感興趣的小伙伴可以跟隨小編學(xué)習(xí)一下
    2022-02-02
  • C++之函數(shù)的重載

    C++之函數(shù)的重載

    這篇文章主要介紹了c++函數(shù)重載的相關(guān)知識(shí),文章講解的非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2021-11-11
  • OpenCV利用對(duì)比度亮度變換實(shí)現(xiàn)水印去除

    OpenCV利用對(duì)比度亮度變換實(shí)現(xiàn)水印去除

    OpenCV中去除水印最常用的方法是inpaint,通過(guò)圖像修復(fù)的方法來(lái)去除水印。本文將介紹另一種方法:利用對(duì)比度亮度變換去除水印,需要的朋友可以參考一下
    2021-11-11
  • C語(yǔ)言實(shí)現(xiàn)校運(yùn)動(dòng)會(huì)項(xiàng)目管理系統(tǒng)

    C語(yǔ)言實(shí)現(xiàn)校運(yùn)動(dòng)會(huì)項(xiàng)目管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)校運(yùn)動(dòng)會(huì)項(xiàng)目管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • C語(yǔ)言基礎(chǔ)之格式化輸出控制長(zhǎng)度

    C語(yǔ)言基礎(chǔ)之格式化輸出控制長(zhǎng)度

    這篇文章主要介紹了C語(yǔ)言基礎(chǔ)之格式化輸出控制長(zhǎng)度的相關(guān)資料,需要的朋友可以參考下
    2017-04-04
  • C語(yǔ)言中的socket編程實(shí)例代碼

    C語(yǔ)言中的socket編程實(shí)例代碼

    這篇文章主要介紹了如何用C語(yǔ)言實(shí)現(xiàn)socket編程,文中代碼非常詳細(xì),供大家學(xué)習(xí)參考,感興趣的朋友可以了解下
    2020-06-06
  • Qt實(shí)現(xiàn)網(wǎng)絡(luò)聊天室的示例代碼

    Qt實(shí)現(xiàn)網(wǎng)絡(luò)聊天室的示例代碼

    本文主要介紹了Qt實(shí)現(xiàn)網(wǎng)絡(luò)聊天室,實(shí)現(xiàn)一個(gè)在線聊天室, 使用tcp對(duì)客戶端和服務(wù)器端進(jìn)行通訊。具有一定的參考價(jià)值,具有一定的參考價(jià)值,
    2021-06-06

最新評(píng)論

革吉县| 泸州市| 增城市| 民和| 三门县| 昭觉县| 德兴市| 庆云县| 瑞金市| 龙南县| 金华市| 鸡西市| 灌南县| 肇东市| 盘锦市| 阿合奇县| 穆棱市| 台南县| 西和县| 炎陵县| 漳州市| 阳原县| 丹寨县| 长沙县| 卢龙县| 聂荣县| 乐山市| 饶阳县| 韩城市| 镇江市| 达日县| 临泉县| 深泽县| 临湘市| 称多县| 德安县| 吐鲁番市| 苏尼特左旗| 五台县| 内黄县| 镇原县|