天天看點

C++ 函數模闆與類模闆

1-1 為什麼要一用函數模闆呢。

#include <iostream>
using namespace std;
/*
void myswap(int &a, int &b)
{
    int t = a;
    a = b;
    b = t;
}

void myswap(char &a, char &b)
{
    char t = a;
    a = b;
    b = t;
}
*/

//template 關鍵字告訴C++編譯器 我要開始泛型了.你不要随便報錯  
//資料類型T 參數化資料類型
template <typename T>
void myswap(T &a, T &b)
{
    T t;
    t = a;
    a = b;
    b = t;
}

void main()
{
    //char a = 'c';

    int  x = ;
    int  y = ;
    myswap(x, y); //自動資料類型 推導的方式 

    float a = ;
    float b = ;

    myswap(a, b); //自動資料類型 推導的方式 
    myswap<float>(a, b); //顯示類型調用 

    cout<<"hello..."<<endl;
    system("pause");
    return ;
}
           

1-2 函數模闆可以做函數的參數

#include <iostream>
using namespace std;

template<typename T, typename T2>
void sortArray(T *a, T2 num)
{
    T tmp ;
    int i, j ;
    for (i=; i<num; i++)
    {
        for (j=i+; j<num; j++)
        {
            if (a[i] < a[j])
            {
                tmp = a[i];
                a[i] = a[j];
                a[j] = tmp;
            }
        }
    }
}

template<class T>
void pirntArray(T *a, int num)
{
    int i = ;
    for (i=; i<num; i++)
    {
        cout<<a[i]<<" ";
    }
}

void main()
{
    int num = ;
    char a[] = "ddadeeettttt";
    num = strlen(a);

    printf("排序之前\n");
    pirntArray<char>(a, num);

    sortArray<char, int>(a, num); //顯示類型調用 模闆函數 <>
    printf("排序之後\n");
    pirntArray<char>(a, num);
    cout<<"hello..."<<endl;
    system("pause");
    return ;
}
           

1-3 函數模闆遇上函數重載

函數模闆和普通函數差別結論:

函數模闆不允許自動類型轉化

普通函數能夠進行自動類型轉換

函數模闆和普通函數在一起,調用規則:

1 函數模闆可以像普通函數一樣被重載

2 C++編譯器優先考慮普通函數

3 如果函數模闆可以産生一個更好的比對,那麼選擇模闆

不妨看下面的案例分析一波:

#include <iostream>
using namespace std;

template <typename T>
void myswap(T &a, T &b)
{
    T t;
    t = a;
    a = b;
    b = t;
    cout<<"myswap 模闆函數do"<<endl;
}

void myswap(char &a, int &b)
{
    int t;
    t = a;
    a = b;
    b = t;
    cout<<"myswap 普通函數do"<<endl;
}

void main()
{
    char cData = 'a';
    int  iData = ;

    //myswap<int>(cData, iData);  //結論 函數模闆不提供隐式的資料類型轉換  必須是嚴格的比對

    myswap(cData, iData); 
    //myswap(iData, cData);

    cout<<"hello..."<<endl;
    system("pause");
    return ;
}
           

1-4 函數模闆機制結論:

編譯器并不是把函數模闆處理成能夠處理任意類的函數

編譯器從函數模闆通過具體類型産生不同的函數

編譯器會對函數模闆進行兩次編譯

在聲明的地方對模闆代碼本身進行編譯;在調用的地方對參數替換後的代碼進行編譯。

2.1 可以這樣聲明和使用類模闆:

1) 先寫出一個實際的類。由于其語義明确,含義清楚,一般不會出錯。

2) 将此類中準備改變的類型名(如int要改變為float或char)改用一個自己指定的虛拟類型名.

3) 在類聲明前面加入一行,格式為:

如:

template <class numtype> //注意本行末尾無分号
    class Compare
    {…}; //類體
           

4) 用類模闆定義對象時用以下形式:

類模闆名<實際類型名> 對象名;
    類模闆名<實際類型名> 對象名(實參表列);
           

如:

Compare<int> cmp;
    Compare<int> cmp(,);
           

5)如果在類模闆外定義成員函數,應寫成類模闆形式:

template <class 虛拟類型參數>
      函數類型 類模闆名<虛拟類型參數>::成員函數名(函數形參表列) {…}
           

2.2 關于類模闆的幾點說明:

1) 類模闆的類型參數可以有一個或多個,每個類型前面都必須加class,如:

template <class T1,class T2>
    class someclass
    {…};
           

在定義對象時分别代入實際的類型名,如:

someclass<int,double> obj;
           

2) 和使用類一樣,使用類模闆時要注意其作用域,隻能在其有效作用域内用它定義對象。

3) 模闆可以有層次,一個類模闆可以作為基類,派生出派生模闆類。

2.3 類模闆在項目開發中的應用

小結

 模闆是C++類型參數化的多态工具。C++提供函數模闆和類模闆。

 模闆定義以模闆說明開始。類屬參數必須在模闆定義中至少出現一次。

 同一個類屬參數可以用于多個模闆。

 類屬參數可用于函數的參數類型、傳回類型和聲明函數中的變量。

 模闆由編譯器根據實際資料類型執行個體化,生成可執行代碼。執行個體化的函數。

模闆稱為模闆函數;執行個體化的類模闆稱為模闆類。

 函數模闆可以用多種方式重載。

 類模闆可以在類層次中使用 。

繼續閱讀