【高質量C++/C總結3】泛型編程——Template模板

說在開始:

我提煉了《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了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章