template之模板注意事項

前言

在分析STL之前, 我們需要先對template做一個回憶, 可能我總結的內容你都會了, 也可能你沒有了印象了, 但是我還是希望你先瀏覽一下template的用法. 畢竟STL全部都涉及到了模板, 而template是學習STL的基礎.

template使用

template的使用大大提高了代碼的複用性, 抽象性.

  1. 類模板實例化時並不是每個成員函數都實例化了, 而是使用到了哪個成員函數, 那個成員函數才實例化.
/* ***** 1 *******/
template<class T>
class point
{
	public:
		point() : x(0), y(0) {}
		point(T x, T y) : x(x), y(y) {}
		T getX() const   { x = y;  return x; }	// 一般是無法通過編譯的, x不允許被修改, 但是這裏並沒有報錯
	private:
		T x;
		T y;
};
/* ***** 2 *******/
#define T int
class point
{
	public:
		point() : x(0), y(0) {}
		point(T x, T y) : x(x), y(y) {}
		T getX() const   { x = y;  return x; }
	private:
		T x; T y;
};

成員函數getX()應該無法通過編譯, 就像實例2一樣, 但是因爲模板中沒有使用到函數getX(), 也就沒有實例化getX, 所以就沒有出現編譯報錯. 實例2必須在編譯的時候就要檢查所有的成員即函數.

不是所有的模板都只能在運行時纔會被實例化, 比如非類型模板參數就能在編譯時期就已經實例化了, 這裏主要說的是類模板, 不要混淆了.

  1. 可以把類模板和函數模板結合起來, 定義一個含有成員函數模板的類模板.
template<class T>
class point
{
	public:
		point() : x(0), y(0) {}
		point(T x, T y) : x(x), y(y) {}
		template<class U>	// 定義了另一個的模板參數類型
			void print(U x);
	private:
		T x;
		T y;
};

// 這裏兩個都要寫出來
template<class T>
template<class U>
void point<T>::print(U x)
{
	std::cout << this->x + x;
}

int main()
{
	point<int> p;
	p.print(3.14);	// 因爲是模板函數, 所以交給編譯器自行推導

	exit(0);
}
  1. 類模板中可以聲明static成員, 在類外定義的時候要增加template相關的關鍵詞, 並且需要注意每個不同的模板實例都會有一個獨有的static成員對象.
template<class T>
class tmp
{
	public:
		static T t;
};

template<class T>
T tmp<T>::t = 0;

int main()
{
	tmp<int> t1;
	tmp<int> t2;
	tmp<double> t3;
	t1.t = 1;
	std::cout << "t1.t = " << t1.t << endl;
	std::cout << "t2.t = " << t2.t << endl;
	cout << "t3.t = " << t3.t << endl;

	exit(0);
}

輸出結果:

t1.t = 1
t2.t = 1
t3.t = 0

模板中的static是在每個不同的類型實例化一個, 相同類型的實例化對象共享同一個參數. 所以這裏的t1, t2中哦t都是同一個實例化變量, 是共享的.

總結

本節只是簡單講了template在實例化時期和使用static, 嵌套模板的使用和注意, 下一節着重分析template的非類型參數.

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