C++模板開(kāi)發(fā)分為兩類:
-
模板函數(shù)開(kāi)發(fā)
-
模板類開(kāi)發(fā)
模板函數(shù)語(yǔ)法:
template <class type> ret-type func-name(parameter list)
{
// 函數(shù)的主體
}
template是關(guān)鍵字,<class type>表示指定的類型(類似java的泛型)诞吱,ret-type表示返回類型
func-name(parameter list):函數(shù)名稱和參數(shù)
- 例子:
#include <iostream>
#include <string>
using namespace std;
//模板函數(shù)
template <typename T>
inline T const& Max (T const& a, T const& b)
{
return a < b ? b:a;
}
int main ()
{
int i = 39;
int j = 20;
cout << "Max(i, j): " << Max(i, j) << endl;
double f1 = 13.5;
double f2 = 20.7;
cout << "Max(f1, f2): " << Max(f1, f2) << endl;
string s1 = "Hello";
string s2 = "World";
cout << "Max(s1, s2): " << Max(s1, s2) << endl;
return 0;
}
模板類語(yǔ)法:
template <class type> class class-name {
...
}
template是關(guān)鍵字,<class type>表示指定的類型竭缝,class-name表示類名
例子:
#include <iostream>
#include <vector>
#include <cstdlib>
#include <string>
#include <stdexcept>
using namespace std;
template <class T>
class Stack {
private:
vector<T> elems; // 元素
public:
void push(T const&); // 入棧
void pop(); // 出棧
T top() const; // 返回棧頂元素
bool empty() const{ // 如果為空則返回真房维。
return elems.empty();
}
};
template <class T>
void Stack<T>::push (T const& elem)
{
// 追加傳入元素的副本
elems.push_back(elem);
}
template <class T>
void Stack<T>::pop ()
{
if (elems.empty()) {
throw out_of_range("Stack<>::pop(): empty stack");
}
// 刪除最后一個(gè)元素
elems.pop_back();
}
template <class T>
T Stack<T>::top () const
{
if (elems.empty()) {
throw out_of_range("Stack<>::top(): empty stack");
}
// 返回最后一個(gè)元素的副本
return elems.back();
}
int main()
{
try {
Stack<int> intStack; // int 類型的棧
Stack<string> stringStack; // string 類型的棧
// 操作 int 類型的棧
intStack.push(7);
cout << intStack.top() <<endl;
// 操作 string 類型的棧
stringStack.push("hello");
cout << stringStack.top() << std::endl;
stringStack.pop();
stringStack.pop();
}
catch (exception const& ex) {
cerr << "Exception: " << ex.what() <<endl;
return -1;
}
}
上面的模板函數(shù)和模板類的例子,都是定義和聲明在同一個(gè)文件中抬纸,但是如果按照傳統(tǒng)的C++類開(kāi)發(fā)咙俩,類的聲明放H頭文件,定義方法CPP源文件松却,這個(gè)時(shí)候編譯會(huì)報(bào)錯(cuò)暴浦,提示成員函數(shù)未定義溅话。這個(gè)問(wèn)題在個(gè)人開(kāi)發(fā)中一直不解,最后在網(wǎng)上搜索找到了合理的解釋 :
在分離式編譯的環(huán)境下歌焦,編譯器編譯某一個(gè).cpp文件時(shí)并不知道另一個(gè).cpp文件的存在飞几,也不會(huì)去查找[當(dāng)遇到未決符號(hào)時(shí)它會(huì)寄希望于連接器]。這種模式在沒(méi)有模板的情況下運(yùn)行良好独撇,但遇到模板時(shí)就傻眼了屑墨,因?yàn)槟0鍍H在需要的時(shí)候才會(huì)具現(xiàn)化出來(lái),所以纷铣,當(dāng)編譯器只看到模板的聲明時(shí)卵史,它不能具現(xiàn)化該模板,只能創(chuàng)建一個(gè)具有外部連接的符號(hào)并期待連接器能夠?qū)⒎?hào)的地址決議出來(lái)搜立。然而當(dāng)實(shí)現(xiàn)該模板的.cpp文件中沒(méi)有用到模板的具現(xiàn)體時(shí)以躯,編譯器懶得去具現(xiàn),所以啄踊,整個(gè)工程的.obj中就找不到一行模板具現(xiàn)體的二進(jìn)制代碼忧设,于是連接器也黔
總之,在模板開(kāi)發(fā)過(guò)程中颠通,聲明和定義必須放在一個(gè)文件中址晕。當(dāng)然,這個(gè)問(wèn)題顿锰,也是有解決方案的谨垃,可以參考C++ 模板類的聲明與實(shí)現(xiàn)分離問(wèn)題
參考文獻(xiàn)http://blog.csdn.net/u012750314/article/details/52770847
這是模板分離開(kāi)發(fā)的實(shí)現(xiàn)可以借鑒:
http://www.reibang.com/p/3a7a41d46645