天天看點

CPP_template

泛型程式設計是獨立于任何特定類型的方式編寫代碼。模闆是泛型程式設計的基礎,模闆使程式員能夠快速建立具有類型安全的類庫集合和函數集合,它的實作,友善了大規模的軟體開發。

模闆提供通用類型和通用函數,定義中包含template,和一對尖括号<>,尖括号裡面是模闆參數。模闆參數與普通參數的差別在于,模闆參數不僅可以傳變量和值,還可以傳類型。模闆參數中定義類型可以使用關鍵字typename或class(效果一樣,有的開發者為區分,函數使用typename,類使用class,實際等同);參數名預設是T,可以為任意字元,效果等同,隻是T較常用,預設。

模闆應放到頭檔案中。模闆本質上就是一種宏定義。

一. 函數模闆

template<typename T> 
傳回類型 function(形式參數表)
{
    //函數定義體
}      

template ---- 聲明建立模闆

typename ---- 表明其後面的符号是一種資料類型,可以用class代替

T ---- 通用資料類型,名稱可以替換,通常為大寫字母

template <class T>
void myswap(T &a, T &b)
{
    T temp = a;
    a = b;
    b = temp;
}      

使用函數模闆有兩種方式:自動類型推導、顯示指定類型

void test01()
{
    int a = 10, b = 20;
//    myswap(a, b);
    myswap<int>(a, b);
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;      

模闆的目的是為了提高複用性,将類型參數化。

注:1)自動類型推導,必須推導出一緻的資料類型T才可以使用。

2)模闆必須要确定出T的資料類型,才可以使用。(比如函數沒有參數且不能自動推導出T類型)

template<class T>
void func()
{
    cout <<  "call func" << endl;
}

int main()
{
//    func();  // 不能推導出T類型
    func<int>();
    return 0;
}      

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

普通函數調用可以發生自動類型轉換(隐式類型裝換);函數模闆調用時如果利用自動類型推導,不會發生隐式類型轉換;如果利用顯示指定類型的方式,可以發生隐式類型轉換。

建議使用顯示指定類型的方式,調用函數模闆,因為可以自己确定通用類型T。

普通函數與函數模闆的調用規則(函數重載時):

1)如果函數模闆和普通函數都可以實作,優先調用普通函數;

2)可以通過空模闆參數清單來強制調用函數模闆;myPrintf<>(a, b);

3)函數模闆也可以發生重載;

4)如果函數模闆可以産生更好的比對,優先調用函數模闆。

建議在使用模闆時,不要提供普通函數(兩者不要同時出現)。

模闆局限性:自定義類型操作

C++為了解決自定義資料類型的無法正常運作問題,提供模闆的重載,為這些特定的類型提供具體化的模闆。

#include <iostream>
#include <cstdlib>
#include <unistd.h>
#include <string>

using namespace std;

class Person
{
public:
    Person(string name, int age){
        this->m_name = name;
        this->m_age = age;
    }

    string m_name;
    int m_age;
};

template <class T>
bool myCompare(T &a, T&b)
{
    if(a == b){
        return true;
    } else {
        return false;
    }
}

// 利用具體Person的版本實作代碼,具體化優先調用
template<> bool myCompare(Person &p1, Person &p2)
{
    if(p1.m_name == p2.m_name && p1.m_age == p2.m_age){
        return true;
    } else {
        return false;
    }
}

void test02()
{
    Person p1("Tom", 10);
    Person p2("Tom", 10);
    cout << myCompare(p1, p2) << endl;
}

int main(int argc, char *argv[])
{
    test02();

    pause();
    return 0;
}      

利用具體化的模闆可以解決自定義類型的通用化。

學習模闆并不是為了能寫模闆,而是在STL能夠運用系統提供的模闆。

二. 類模闆

template <模闆參數表> class 類名{};

template<class T1, class T2>
class 類{
    類成員聲明;
};      

T是占位符類型名稱,可以在類被執行個體化的時候進行指定。您可以使用一個逗号分隔的清單來定義多個泛型資料類型。

在類模闆以外定義成員函數

template <模闆參數表> 類型名 類名<參數清單>::函數名(參數表)

模闆類中的函數都是模闆函數。

template <class T> Node<T>::~Node()

{

......

}

參考:

繼續閱讀