1.模板類與模版函數
1.1 模版類
template <類型參數表>
class 類模板名{
成員函數和成員變量
};
類型參數表的寫法如下:
class類塑參數1, class類型參數2, ...
或者
typename類塑參數1, typename類型參數2, ...
示例:
template <class T,class M>
class Test {
T obj;
};
template <typename T, typename M>
class MyClass {
T obj;
};
類模板中的成員函數放到類模板定義外面寫時的語法如下:
template <類型參數表>
返回值類型 類模板名<類型參數名列表>::成員函數名(參數表)
{
...
}
template <typename T, typename M>
void MyClass<T, M>::Func1()
{
}
1.2模版類的派生
1.2.1從模板類派生模板類
template <class T>
class base
{
};
template <class T,class F>
class derive :public base<T>
{
F f;
T t;
};
1.2.2從模板類派生非模板類,基類在被繼承時必須實例化
template <class T>
class base
{
};
class derive :public base<int>
{
};
1.3模版函數
template<類型形式參數表>
返回類型 函數名(形式參數表)
{
... //函數體
}
示例
template <class M, class E>
bool Compare(M a, E b)
{
return true;
}
函數模板不會被編譯,而是在調用點實例化一個所指定類型參數的模板函數去調用。(函數模板—>實例化—>模板函數)也就是說,使用模板時並沒有省略系統要編譯的代碼,只是把這些代碼讓系統通過我們定義的模板自己完成編寫。
一般情況下,模板的定義都會寫在頭文件中,應用時直接包含頭文件即可。如果採用頭文件聲明,cpp定義的話,會發現在編譯鏈接時出現了鏈接錯誤(無法解析的外部符號)這是因爲模板本身是不參加編譯鏈接過程的,只有它實例化的模板函數纔會進行編譯和連接,不進行編譯鏈接就沒有任何的實例化,而實例化是在編譯過程進行的,編譯時各個cpp文件都是單獨編譯,因此單獨在一個cpp文件中的模板定義也就不會產生符號,相當於這個函數只有聲明沒有函數體,那麼另外一個文件中使用他時不知道如何實例化函數體,會出現找不到它的定義,因此就會出現鏈接錯誤.