說在開始:
我提煉了《C++ Primer》、《侯捷C++》、《高質量程序設計指南——C/C++語言》等資料中的重要部分,並總結成此博文。其中涉及到許多我個人對C++的理解,如若有不合理之處,還請朋友們多多指出,我會虛心接受每一個建議。
作者:憨豆酒(YinDou),聯繫我[email protected],熟悉圖形學,圖像處理領域,本章的源代碼可在此倉庫中找到: https://github.com/douysu/person-summary 如果大家發現錯誤以及不合理之處,還希望多多指出。
內容介紹
Template是C++泛型編程中非常重要的一環,Template常用在泛型類和函數中。在C++標準庫中也經常看到Template的身影。可以說,Template是一個優秀的C++框架中重要的一環,例如那些優秀的C++框架,OpenGL,OpenCV,STL等等。Template是一非常大的話題,該篇博文只會讓您對Template產生基本的認識,要想熟練掌握,需要修讀更多的書籍和資料。
那麼Template爲什麼會這麼重要?首先是一個具體的案例,接着在分析一下algorithm中的max源碼,這樣可以對Template有更深的體會。
在開始之前我們思考一個我們經常遇到的情況,看一下以下代碼。
int a = 2, b = 3;
int c = max(a, b);
float af = 2.0f, bf = 3.0f;
float cf = max(af, bf);
stack(int a) s1;//存放int類型數據的棧
stack(float b) s2;//存放float類型數據的棧
1、要想實現以上功能需要寫幾個max函數?
2、要想實現以上功能需要寫幾個類?
在沒有函數模板時,想必只能通過此種方式完成:
int max(int a, int b)
{
if (a > b) { return a; }else { return b; }
}
float max(float a, float b)
{
if (a > b) { return a; }else { return b; }
}
class stack
{
public:
stack(int a)
}
class stack2
{
public:
stack(float a)
}
在寫程序時,一定要注意,當頻繁使用ctrl+c和ctrl+v時往往都不是啥好事。上面的代碼會有以下幾種問題:(1)代碼較長,抒寫時耗費時間。(2)需求改變時,修改不方便,這裏不在多提怎麼不方便了。每個函數都需要修改一遍,傻子都不喜歡做吧。
模板就是爲了解決此種情況提出的。
使用方法
以以下此段代碼爲例。
template <typename T>
T add(T a, T b) {
return a + b;
}
T可以是任何名稱,不過我觀察大部分C++開源庫中都使用的是T。這裏T你可以想象成是一個類型,與int相似。
函數模板
//FunctionTemplate.cpp
template <typename T>
T const& add(T const& a, T const& b) {//創建函數模板
return a + b;
}
int main() {
int i1 = add(1, 2);
float f2 = add(3.3f, 4.2f);
double d3 = add(2,2);
std::cout << i1 << std::endl;
std::cout << f2 << std::endl;
std::cout << d3 << std::endl;
std::cin.get();
}
通過此種方式,add函數可接受任何類型的參數。
類模板
//ClassTemplate.h
#ifndef CLASSTEMPLATE
#define CLASSTEMPLATE
template <class T>
class ClassTemplate
{
public:
ClassTemplate(T const& widthIn, T const& heightIn)
: width(widthIn), height(heightIn)
{
}
T const& CalculateArea();
private:
T width;
T height;
};
template <class T>
T const& ClassTemplate<T>::CalculateArea() {
return width * height;
}
#endif // !CLASSTEMPLATE
//main.cpp
#include <iostream>
#include "ClassTemplate.h"
using namespace std;
int main() {
ClassTemplate<int> s1(1,2);
ClassTemplate<float> s2(1.0f, 2.0f);
int area=s1.CalculateArea();
float areaf = s2.CalculateArea();
cout << "計算出的int面積是" << area<< "計算出的float面積是" << areaf << endl;
std::cin.get();
}
在main.cpp代碼ClassTemplate s1(1,2);ClassTemplate s2(1.0f, 2.0f);中可以看出,接收了不同的參數。當然你可以使用此種方式構造棧。
typename和class的區別
以上兩種方式,使用typename和class是沒有區別的,兩種方式都可以定義模板。
template <typename T>
template <class T>
但是有一種情況就需要區別對待typename和class了。