1. 程式人生 > >C++之模板

C++之模板

模板的引入

在討論模板之前,先看一下這個經典的交換程式:

#include <iostream>
using namespace std;
void swap1(int& a, int& b) {
	int temp = a; a = b; b = temp;
}
int main() {
	int a = 2, b = 3;
	swap1(a, b);
	cout << "a = " << a << " b = " << b << endl;
	return 0;
}

這裡定義了一個用於交換兩個int型別資料的函式swap1。如果我們還需要一個用於交換float型別資料的函式應該怎麼辦,在不知道模板的情況下,我們很容易想到函式過載

,程式如下:

#include <iostream>
using namespace std;
void swap1(int& a, int& b) {
	int temp = a; a = b; b = temp;
}
void swap1(float& a, float& b) {
	float temp = a; a = b; b = temp;
}
int main() {
	int a = 2, b = 3;
	float c = 2.5, d = 3.5;
	swap1(a, b);
	swap1(c, d);
	cout <<
"a = " << a << " b = " << b << endl; cout << "c = " << c << " d = " << d << endl; return 0; }

這個確實達到了我們的需求,但是如果我們還需要交換其他資料型別的函式則需要增加更多的過載。這裡不同過載之間起始只有資料型別不同,其他的業務都是相同的。因此C++提供了一種泛型程式設計的方法,這是一種獨立於任何特定型別的程式設計方式,可以讓程式不受資料型別的限制

模板就是泛型程式設計的基礎。下面還是通過swap的例子來引入模板:

#include <iostream>
#include <string>
using namespace std;
template<typename T>
void swap1(T& a, T& b) {
	T temp = a; a = b; b = temp;
}
int main() {
	int a = 2, b = 3;
	float c = 2.5, d = 3.5;
	string e = "Hello";
	string f = "World!";
	swap1(a, b);
	swap1(c, d);
	swap1(e, f);
	cout << "a = " << a << " b = " << b << endl;
	cout << "c = " << c << " d = " << d << endl;
	cout << "e = " << e << " f = " << f << endl;
	return 0;
}
a = 3 b = 2
c = 3.5 d = 2.5
e = World! f = Hello

上例通過模板使得演算法和資料型別解耦,從而使得swap1函式可以作用於多種資料型別。

函式模板與類模板

模板一般可分為兩類,函式模板類模板,下面分別介紹兩類模板的格式:

函式模板

template <class type,class type,...>
ret-type func(parameter list)
{
   // 函式體
}

這裡的class可以由typename替換,type為資料型別,多個數據型別由逗號分開。

類模板

template <class type, class type, ...>
class classname{
	//類主體
}

類模板的結構和函式模板的結構非常類似,下面通過類模板使得Point類支援多種資料型別

#include <iostream>
using namespace std;
template <typename T>
struct Point {
public:
	T x, y;
	Point(T a, T b) :x(a), y(b) {};//建構函式1
	Point(T a) :x(a), y(a) {};//建構函式2
};
template <typename T>
Point<T> operator+(const Point<T>& A, const Point<T>& B) {//加
	return Point<T>(A.x + B.x, A.y + B.y);
}
template <typename T>
Point<T> operator-(const Point<T> &A) {//負
	return Point<T>(-A.x, -A.y);
}
template <typename T>
ostream& operator<<(ostream& out, const Point<T>& B) {//流
	out << "(" << B.x << ", " << B.y << ")";
	return out;
}
int main() {
	Point<int> p1(2, 3);
	Point<float> p2(2.5, 3.5);
	cout << p1 << " " << p2 << " " << endl;
	return 0;
}

這樣,我們就可以同時使用不同資料型別的Point物件了。注意在建立物件時必須指明類模板的引數列表,如<int>、<float>等。